CodeForces Global round 8 CF1368D,CF1368E,CF1368F题解

    技术2026-01-22  9

    D. AND, OR and square sum

    首先必须要知道的是: x + y = x A N D y + x O R y x+y=xANDy+xORy x+y=xANDy+xORy 然后就可以发现操作结束后总和不会变。 然后显然可以发现这些数应该使得大的尽可能大,这样才能满足 ∑ i = 1 n a i 2 \sum_{i=1}^n a_i^2 i=1nai2 尽可能大。 然后做法就显然了,对于操作 i , j i,j i,j,其实就是把 a i a_i ai所拥有的 a j a_j aj没有的bit移给 a j a_j aj。 code:

    #include<bits/stdc++.h> #define rb(a,b,c) for(int a=b;a<=c;++a) #define rl(a,b,c) for(int a=b;a>=c;--a) #define LL long long #define IT iterator #define PB push_back #define II(a,b) make_pair(a,b) #define FIR first #define SEC second #define FREO freopen("check.out","w",stdout) #define rep(a,b) for(int a=0;a<b;++a) #define KEEP while(1) #define SRAND mt19937 rng(chrono::steady_clock::now().time_since_epoch().count()) #define random(a) rng()%a #define ALL(a) a.begin(),a.end() #define POB pop_back #define ff fflush(stdout) #define fastio ios::sync_with_stdio(false) #define debug_pair(A) cerr<<A.FIR<<" "<<A.SEC<<endl; using namespace std; const int INF=0x3f3f3f3f; typedef pair<int,int> mp; typedef pair<mp,mp> superpair; int cnt[31]; int main(){ fastio; int n; cin>>n; rb(i,1,n) { int ai; cin>>ai; rep(j,31){ if(ai&(1<<j)) { cnt[j]++; } } } LL res=0; rb(i,1,n){ LL ai=0; rep(j,31){ if(cnt[j]){ ai+=1<<j; cnt[j]--; } } res+=ai*ai; } cout<<res<<endl; return 0; }

    E. Ski Accidents

    *把边反过来:所有的点的入度 ≤ 2 \leq 2 2 * 从前往后考虑,考虑第i个,如果以这个点开始存在一条dangerous path 就关闭这个点。 这样会删掉多少个点呢? 首先,先分一个组。 对于删掉后的图,如果从一个点走出去最多走出去1个(包括这个点)则分到组 G 1 G_1 G1如果2个分到组 G 2 G_2 G2,剩下删掉的分到 G 3 G_3 G3。 由于每一给点的入度 ≤ 2 \leq 2 2所以, ∣ G 2 ∣ ≥ ∣ G 3 ∣ / 2 |G_2|\geq|G_3|/2 G2G3/2,同理 ∣ G 1 ∣ ≥ ∣ G 2 ∣ / 2 |G_1|\geq|G_2|/2 G1G2/2,由于 ∣ G 1 ∣ + ∣ G 2 ∣ + ∣ G 3 ∣ = n |G_1|+|G_2|+|G_3|=n G1+G2+G3=n可得: ( 7 / 4 ) ∗ ∣ G 3 ∣ ≤ n ⇒ ∣ G 3 ∣ ≤ ( 4 / 7 ) ∗ n (7/4)*|G_3|\leq n \Rightarrow|G_3|\leq(4/7)*n (7/4)G3nG3(4/7)n code:

    #include<bits/stdc++.h> #define rb(a,b,c) for(int a=b;a<=c;++a) #define rl(a,b,c) for(int a=b;a>=c;--a) #define LL long long #define IT iterator #define PB push_back #define II(a,b) make_pair(a,b) #define FIR first #define SEC second #define FREO freopen("check.out","w",stdout) #define rep(a,b) for(int a=0;a<b;++a) #define KEEP while(1) #define SRAND mt19937 rng(chrono::steady_clock::now().time_since_epoch().count()) #define random(a) rng()%a #define ALL(a) a.begin(),a.end() #define POB pop_back #define ff fflush(stdout) #define fastio ios::sync_with_stdio(false) #define debug_pair(A) cerr<<A.FIR<<" "<<A.SEC<<endl; using namespace std; const int INF=0x3f3f3f3f; typedef pair<int,int> mp; typedef pair<mp,mp> superpair; int T; int n,m; vector<int> g[200000+2]; bool vis[200000+2]; void solve(){ cin>>n>>m; rb(i,1,n) g[i].clear(),vis[i]=0; rb(i,1,m) { int u,v; cin>>u>>v; g[v].PB(u); } vector<int> res; rb(i,1,n){ bool ok=0; for(auto it:g[i]){ if(ok) break; if(!vis[it]) for(auto it2:g[it]){ if(!vis[it2]){ ok=1; break; } } } if(ok){ vis[i]=1; res.PB(i); } // done:; } cout<<res.size()<<endl; for(auto it:res){ cout<<it<<" "; } cout<<endl; } int main(){ fastio; cin>>T; while(T--) { // cout<<"#\n"; solve(); } return 0; }

    F. Lamps on a Circle

    首先可以发现如果你放了k个后存在一段连续的长度为k的开着的灯,那么这k个灯可以被削掉,这样总数上并没有变。 当然你也不可能故意让对手消掉这么多,换取更优解,毕竟你无法控制对方。 所以上述操作是一次无效操作。 可以获得性质1:

    操作完剩余最长的连续的1长度 < k < k <k

    然后就可以发现如果你的策略最终造成的局面不是很"均匀"那么,对方完全可以在密集的地方删除,所以稀疏的地方就浪费了。 可以获得性质2:

    尽可能均匀

    所以可以大概想到最终的结果是一段一段长度为k的连续的1,中间空着0(1表示亮着),每次点亮k+1个就ok了,因为每次最多消掉k个。其中k可以枚举。 code:

    #include<bits/stdc++.h> #define rb(a,b,c) for(int a=b;a<=c;++a) #define rl(a,b,c) for(int a=b;a>=c;--a) #define LL long long #define IT iterator #define PB push_back #define II(a,b) make_pair(a,b) #define FIR first #define SEC second #define FREO freopen("check.out","w",stdout) #define rep(a,b) for(int a=0;a<b;++a) #define KEEP while(1) #define SRAND mt19937 rng(chrono::steady_clock::now().time_since_epoch().count()) #define random(a) rng()%a #define ALL(a) a.begin(),a.end() #define POB pop_back #define ff fflush(stdout) #define fastio ios::sync_with_stdio(false) #define debug_pair(A) cerr<<A.FIR<<" "<<A.SEC<<endl; using namespace std; const int INF=0x3f3f3f3f; typedef pair<int,int> mp; typedef pair<mp,mp> superpair; bool on[1002],need[1002]; int n,m; void query(vector<int> v){ // cerr<<"?"; cout<<v.size()<<" "; for(auto it: v){ on[it]=1; cout<<it<<" "; } cout<<endl; ff; int pos; cin>>pos; rb(i,1,v.size()){ on[(pos+i-1)%n ? (pos+i-1)%n:n]=0; // cout<<((pos+i-1)%n ? (pos+i-1)%n:n)<<endl; } } int main(){ fastio; cin>>n; if(n<=3){ cout<<0<<endl; ff; return 0; } int best=-INF; rb(i,1,n){ rb(j,1,n) need[j]=0; for(int j=1,cnt=1;j<=n;j++,cnt++){ if(cnt==i+1){ cnt=0; continue; } need[j]=1; } need[n]=0; int tmp=0; rb(j,1,n) tmp+=need[j]; if(tmp>best+i){ best=tmp-i; m=i; } } // cout<<m<<" "<<best<<endl; rb(j,1,n) need[j]=0; for(int j=1,cnt=1;j<=n;j++,cnt++){ if(cnt==m+1){ cnt=0; continue; } need[j]=1; } need[n]=0; while(1){ vector<int> que; rb(i,1,n){ if(need[i]&&!on[i]){ que.PB(i); if(que.size()==m+1) break; } } // cout<<que.size()<<endl; if(que.size()<=1) break; query(que); bool ok=1; rb(i,1,n){ if(need[i]){ if(i>que[que.size()-1]) ok=0; } } if(ok){ break; } } cout<<0<<endl; return 0; }
    Processed: 0.032, SQL: 12