标签:typedef 判断 == air alt 怎么 col prim ios
题目:https://codeforc.es/contest/1529
A. Eshag Loves Big Arrays
题意:略
题解:发现随便取两个不同的数,一定可以删掉大的那个数。所以最后留下的肯定是最小的所有数。
#include<iostream> #include<algorithm> #include<vector> #include<stack> #include<map> #include<cmath> #include<cstring> using namespace std; const int mx=2e5+10; const int inf=1<<30; typedef long long ll; void solve(){ ll t; scanf("%lld", &t); for(ll lp=1;lp<=t;lp++){ ll num, v; scanf("%lld", &num); map<ll,ll>mp; for(ll i=1;i<=num;i++){ scanf("%lld", &v); mp[v]++; } map<ll,ll>::iterator it=mp.begin(); printf("%lld\n", num-(it->second)); } } int main(){ solve(); return 0; }
B. Sifid and Strange Subsequences
题意:求最长子串,让任意两数之差的绝对值大于等于最大数。
题解:
首先最多只有一个正数。假如有两个正数,它俩绝对值之差肯定小于大的数。
所以最优搭配是:所有的负数+1个正数。
但是要判定一下是否有可能两数之差绝对值小于这个正数。(所以要选最小的正数 然后判断是否矛盾。矛盾就去掉正数
#include<iostream> #include<algorithm> #include<vector> #include<stack> #include<map> #include<cmath> #include<cstring> using namespace std; const int mx=1e5+10; typedef long long ll; const ll inf=3e9+10; ll t, num, v[mx]; void solve(){ scanf("%lld", &t); for(ll lp=1;lp<=t;lp++){ scanf("%lld", &num); for(ll i=1;i<=num;i++)scanf("%lld", &v[i]); sort(v+1, v+1+num); ll gs=0, min_dif=inf; ll i=1; ll bef=-inf; while(i<=num && v[i]<=0){ gs++; min_dif=min(min_dif,v[i]-bef); bef=v[i]; i++; } if(i<=num){ min_dif=min(min_dif, v[i]-bef); } if(i<=num && v[i]<=min_dif){ gs++; } printf("%lld\n", gs); } } int main(){ solve(); return 0; }
D. Kavi on Pairing Duty
题意:略。
题解:
以n等于3为例。一共6个点。
然后考虑1号点和5、6相连的可能性。【为什么只考虑5、6之后说】
1和6连,那么2345都空出来了,2345的可能性就是n=2的可能性,答案为3。
1和5连,6只能和2连,那么34空出来了,可能性是n=1的可能性,答案为1。
最后考虑1和2,3,4的连法。【这些情况下 只能是所有都大小相同】
12情况,剩下的也都是相邻相邻。答案+1
13情况没有可能性(可以试着画一下。
14情况,彼此交叉。答案+1。
所以最后答案为3+1+1+1=6。
然后以n=4为例来看看。
考虑1号点和6、7、8相连可能性,对应答案为n=1、2、3的答案,为1+3+6=10。
然后考虑1和2,3,4,5相连可能性。
此时1和2、3、5都可以构成答案。所以答案+3。最后答案为13。
对于求n的答案
第一步:算对应答案为n=1、2、3。。。n-1的答案,这个可以用一个变量tot来记录。每次算一个n的时候就把对应的答案加上去。用tot来记录到n-1为止的答案和。
第二步:算1和2、3、4。。。。n可以构成答案的数量 这一步怎么算↓
为什么n=4的情况可以和2、3、5构成答案呢?
我们来看 相同大小交叉的最小情况
一个不交叉:2个点。
两个交叉:4个点。
三个交叉:6个点。
。。。
以此类推,所以只要2n是2、4、6.。。。2n的倍数。答案就会对应+1。
上面的内容可以转化为只要n是1、2、3。。。n的倍数,答案就会+1。
这里可以对n质因数分解,将上面的内容转化为,质因数可以构造多少个不同的数,答案就对应加多少数。
综上完成了所有内容。可以算了。
#include<iostream> #include<algorithm> #include<vector> #include<stack> #include<map> #include<cmath> #include<cstring> using namespace std; //const int mx=1e2+10; const int mx=1e6+10; const int inf=1<<30; typedef long long ll; const ll mod=998244353; ll two[mx]; ll prime[mx], tot; bool isp[mx]; ll f[mx]; ll fenjie(ll v){ ll ans=1; for(ll j=1;j<=tot;j++){ ll i=prime[j]; ll gs=0; if(i*i>v)break; if(v%i==0){ while(v%i==0){ v/=i; gs++; } ans*=(gs+1); ans%=mod; } } if(v!=1) { ans*=2; ans%=mod; } return ans;//多少种不同的数 } void init(){ isp[1]=true; for(ll i=2;i<mx;i++){ if(isp[i]==false)prime[++tot]=i; for(ll j=1;j<=tot;j++){ if(i*prime[j]>mx)break; isp[i*prime[j]]=true; if(i%prime[j]==0)break; } } } void init2(){ f[1]=1; ll curr_tot=1;//记录之前的答案综合 for(ll i=2;i<mx;i++){ f[i]=curr_tot; f[i]+=fenjie(i); f[i]%=mod; curr_tot+=f[i];//f[1]+f[2]+...+f[i]; curr_tot%=mod; } } void solve(){ init(); init2(); ll v; scanf("%lld", &v); printf("%lld\n", f[v]); } int main(){ solve(); return 0; }
Codeforces Round #722 (Div. 2)
标签:typedef 判断 == air alt 怎么 col prim ios
原文地址:https://www.cnblogs.com/ReflexFox/p/14807505.html