Loading

Noip模拟62 2021.9.26

T1 Set

真就随机化拿了$90$??

不过还是有依据的,毕竟这道题出解的几率很大,随出答案的概率也极大

所以不妨打一个随机化

 1 #include<bits/stdc++.h>
 2 #define int long long
 3 using namespace std;
 4 namespace AE86{
 5     inline int read(){
 6         int x=0,f=1;char ch=getchar();
 7         while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
 8         while(ch>='0'&&ch<='9'){x=(x<<1)+(x<<3)+(ch^48);ch=getchar();}return x*f;
 9     }inline void write(int x,char opt='\n'){
10         char ch[20];int len=0;if(x<0)x=~x+1,putchar('-');
11         do{ch[len++]=x%10+(1<<5)+(1<<4);x/=10;}while(x);
12         for(int i=len-1;i>=0;--i)putchar(ch[i]);putchar(opt);}
13 }using namespace AE86;
14 const int NN=1e6+5;
15 int n,a[NN],has[NN],sum;
16 inline void spj(){
17     int sum=0;
18     for(int i=1;i<=n;i++) a[i]=read()%n;
19     for(int i=1;i<(1<<n);i++){
20         sum=0;
21         for(int j=1;j<=n;j++)
22             if(i&(1<<j-1)) sum+=a[j];
23         if(sum%n==0){
24             write(__builtin_popcount(i));
25             for(int j=1;j<=n;j++) if(i&(1<<j-1)) write(j,' ');
26             return;
27         }
28     }
29     puts("-1");return;
30 }
31 vector<int> pos;
32 namespace WSN{
33     inline short main(){
34         freopen("a.in","r",stdin);
35         freopen("a.out","w",stdout);
36         srand(time(0)^clock());
37         n=read(); int yu; if(n<=20) {spj();return 0;}
38         for(int i=1;i<=n;i++){
39             a[i]=read(); yu=a[i]%n;
40             if(!yu) {printf("1\n %lld\n",i);return 0;}
41             else if(has[n-yu]) {printf("2\n %lld %lld\n",has[n-yu],i);return 0;}
42             has[yu]=i; a[i]=yu; sum+=yu;
43             if(sum%n==0){
44                 write(i); for(int j=1;j<=i;j++) write(j,' ');
45                 puts(""); return 0;
46             }
47         }
48         for(int i=1;i<=n/2+1;i++) if(has[n-i]&&has[i]){
49             printf("2\n %lld %lld\n",has[i],has[n-i]);
50             return 0;
51         }
52         int tim=0,tot=50000000/n;
53         while(tim<tot){
54             sum=0; pos.clear();
55             for(int i=1;i<=n;i++) if(rand()&1){
56                 sum+=a[i]; pos.push_back(i);
57                 if(sum%n==0){
58                     write(pos.size());
59                     for(int j=0;j<pos.size();j++)
60                         write(pos[j],' ');
61                     return 0;
62                 }
63             }
64             ++tim;
65         }
66         puts("-1");
67         return 0;
68     }
69 }
70 signed main(){return WSN::main();}
rand 90

考虑正解,发现如果维护一个前缀和的余数,他的答案只能是$0~n-1$

但是一共有$n+1$个前缀和,那么必定有两个前缀和的余数是相等的,那么他们之间的所有数加起来就是答案

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 namespace AE86{
 4     inline int read(){
 5         int x=0,f=1;char ch=getchar();
 6         while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
 7         while(ch>='0'&&ch<='9'){x=(x<<1)+(x<<3)+(ch^48);ch=getchar();}return x*f;
 8     }inline void write(int x,char opt='\n'){
 9         char ch[20];int len=0;if(x<0)x=~x+1,putchar('-');
10         do{ch[len++]=x%10+(1<<5)+(1<<4);x/=10;}while(x);
11         for(int i=len-1;i>=0;--i)putchar(ch[i]);putchar(opt);}
12 }using namespace AE86;
13 const int NN=1e6+5;
14 int n,a[NN],has[NN],sum;
15 namespace WSN{
16     inline short main(){
17         freopen("a.in","r",stdin);
18         freopen("a.out","w",stdout);
19         srand(time(0)^clock());
20         n=read();
21         for(int i=1,x;i<=n;i++){
22             x=read()%n; sum=(sum+x)%n;
23             if(!x) {printf("1\n %d\n",i);return 0;}
24             if(!sum||has[sum]){
25                 write(i-has[sum]); for(int j=has[sum]+1;j<=i;j++) write(j,' ');
26                 puts(""); return 0;
27             }
28             if(!has[sum]) has[sum]=i;
29         }
30         puts("-1");
31         return 0;
32     }
33 }
34 signed main(){return WSN::main();}
View Code

 

T2 Read

和$codeforces$里面一道题挺像,于是就只拿到了三十分,由于$n$太大了

正解与那道题做法不同,但是$fengwu$用那道题加上一个分块的思想切了这道题,超巨

正解只是多开两个变量$id,cnt$,考虑一种书要是超过$\frac{n}{2}+1$那么答案必定为$0$

那么我们只需要找到 最多书的个数 减去 剩下的书个数$+1$ 就是答案

然后用$id,cnt$维护一波最值即可

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 namespace AE86{
 4     inline int read(){
 5         int x=0,f=1;char ch=getchar();
 6         while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
 7         while(ch>='0'&&ch<='9'){x=(x<<1)+(x<<3)+(ch^48);ch=getchar();}return x*f;
 8     }inline void write(int x,char opt='\n'){
 9         char ch[20];int len=0;if(x<0)x=~x+1,putchar('-');
10         do{ch[len++]=x%10+(1<<5)+(1<<4);x/=10;}while(x);
11         for(int i=len-1;i>=0;--i)putchar(ch[i]);putchar(opt);}
12 }using namespace AE86;
13 int M,K,C[1005],X[1005],Y[1005],Z[1005],S,last,id,cnt,N;
14 namespace WSN{
15     inline short main(){
16         freopen("b.in","r",stdin);
17         freopen("b.out","w",stdout);
18         M=read(); K=read();
19         for(int i=1;i<=M;i++) C[i]=read(),N+=C[i];
20         for(int i=1;i<=M;i++) X[i]=read();
21         for(int i=1;i<=M;i++) Y[i]=read();
22         for(int i=1;i<=M;i++) Z[i]=read();
23         S=(1<<K)-1;
24         for(int i=1;i<=M;i++){
25             last=X[i];
26             if(!cnt) id=last,cnt=1;
27             else if(id==last) ++cnt;
28             else --cnt;
29             for(int j=1;j<C[i];j++){
30                 last=(last*Y[i]+Z[i])&S;
31                 if(!cnt) id=last,cnt=1;
32                 else if(id==last) ++cnt;
33                 else --cnt;
34             }
35         }
36         if(cnt<=0) return puts("0"),0; cnt=0;
37         for(int i=1;i<=M;i++){
38             last=X[i];
39             if(last==id) ++cnt;
40             for(int j=1;j<C[i];j++){
41                 last=(last*Y[i]+Z[i])&S;
42                 if(last==id) ++cnt;
43             }
44         }
45         write(max(cnt*2-N-1,0));
46         return 0;
47     }
48 }
49 signed main(){return WSN::main();}
View Code

 

T3 题目交流通道

考场上以为是有向图,觉得第一个点的$30$分复杂度$O(5^{12})$会炸

但是是无向图所以只有$O(5^6)$,所以我就没打暴力,所以就从$rk8->rk10$

是个人都拿了这题的三十分。。。。

场上以为是矩阵快速幂的变形,后来才发现不对劲

 

 按照题解上的打一个并查集,然后做就可以,容斥考虑两个团之间的点的强制选择问题

 1 #include<bits/stdc++.h>
 2 #define int long long
 3 using namespace std;
 4 namespace AE86{
 5     inline int read(){
 6         int x=0,f=1;char ch=getchar();
 7         while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
 8         while(ch>='0'&&ch<='9'){x=(x<<1)+(x<<3)+(ch^48);ch=getchar();}return x*f;
 9     }inline void write(int x,char opt='\n'){
10         char ch[20];int len=0;if(x<0)x=~x+1,putchar('-');
11         do{ch[len++]=x%10+(1<<5)+(1<<4);x/=10;}while(x);
12         for(int i=len-1;i>=0;--i)putchar(ch[i]);putchar(opt);}
13 }using namespace AE86;
14 const int mod=998244353,NN=401;
15 
16 int n,k,d[NN][NN],C[NN][NN],ans=1;
17 int fa[NN],siz[NN]; bool vis[NN];
18 int num,FA[NN];
19 pair<int,int> dis[NN][NN]; vector<int> son[NN];
20 bool inq[NN][NN];
21 int g[NN],f[NN];
22 
23 inline int getfa(int x){return fa[x]=(fa[x]==x?x:getfa(fa[x]));}
24 inline int qmo(int a,int b,int ans=1){
25     int c=mod; while(b){
26         if(b&1) ans=ans*a%c;
27         b>>=1; a=a*a%c;
28     } return ans;
29 }
30 
31 namespace WSN{
32     inline short main(){
33         freopen("c.in","r",stdin);
34         freopen("c.out","w",stdout);
35         n=read(); k=read(); C[0][0]=1;
36         for(int i=1;i<=n;i++){ C[i][0]=C[i][i]=1;
37             for(int j=1;j<=i;j++) C[i][j]=(C[i-1][j]+C[i-1][j-1])%mod;
38         } for(int i=1;i<=n;i++) for(int j=1;j<=n;j++) d[i][j]=read();
39         for(int i=1;i<=n;i++) for(int j=1;j<=n;j++){
40             if(d[i][j]!=d[j][i]) return puts("0"),0;
41             if(d[i][i]!=0) return puts("0"),0; if(d[i][j]>k) return puts("0"),0;
42         } for(int k=1;k<=n;k++) for(int i=1;i<=n;i++) for(int j=1;j<=n;j++) 
43             if(i!=j && i!=k && j!=k) if(d[i][j]>d[i][k]+d[k][j]) return puts("0"),0;
44         for(int i=1;i<=n;i++) fa[i]=i,siz[i]=1;
45         for(int i=1;i<n;i++) for(int j=i+1;j<=n;j++) if(d[i][j]==0){
46             int x=getfa(i),y=getfa(j); if(x!=y) fa[y]=x,siz[x]+=siz[y];
47         } for(int i=1;i<=n;i++)
48             if(!vis[getfa(i)]) FA[++num]=getfa(i),vis[getfa(i)]=1,son[getfa(i)].push_back(getfa(i));
49             else son[getfa(i)].push_back(i);
50         for(int i=1;i<num;i++) for(int j=i+1;j<=num;j++){
51             int f=FA[i],ff=FA[j];
52             dis[f][ff]=dis[ff][f]=make_pair(d[son[f][0]][son[ff][0]],siz[f]*siz[ff]);
53         }for(int k=1;k<=num;k++) for(int i=1;i<=num;i++)
54             for(int j=1;j<=num;j++) if(i!=j && i!=k && j!=k)
55                 if(dis[FA[i]][FA[j]].first==dis[FA[i]][FA[k]].first+dis[FA[k]][FA[j]].first)
56                     inq[FA[i]][FA[j]]=inq[FA[j]][FA[i]]=1;
57         for(int i=1;i<num;i++) for(int j=i+1;j<=num;j++){
58             int f=FA[i],ff=FA[j];
59             if(inq[f][ff]) ans=ans*qmo(k-dis[f][ff].first+1,dis[f][ff].second)%mod;
60             else ans=ans*(qmo(k-dis[f][ff].first+1,dis[f][ff].second)-qmo(k-dis[f][ff].first,dis[f][ff].second)+mod)%mod;
61         } for(int i=1;i<=n;i++) g[i]=qmo(k+1,C[i][2]);
62         for(int i=1;i<=n;i++){
63             int tmp=0;
64             for(int j=1;j<=i-1;j++)
65                 tmp=(tmp+f[j]*g[i-j]%mod*C[i-1][j-1]%mod*qmo(k,j*(i-j))%mod)%mod;
66             f[i]=(g[i]-tmp+mod)%mod;
67         } for(int i=1;i<=num;i++) ans=ans*f[siz[FA[i]]]%mod; write(ans);
68         return 0;
69     }
70 }
71 signed main(){return WSN::main();}
View Code

(测试点非常水,大样例没过就$A$了,不过放心这是真$AC$代码)

 

T4 题目难度提升

没时间了

 

 

 1 #include<bits/stdc++.h>
 2 #define int long long
 3 using namespace std;
 4 namespace AE86{
 5     inline int read(){
 6         int x=0,f=1;char ch=getchar();
 7         while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
 8         while(ch>='0'&&ch<='9'){x=(x<<1)+(x<<3)+(ch^48);ch=getchar();}return x*f;
 9     }inline void write(int x,char opt='\n'){
10         char ch[20];int len=0;if(x<0)x=~x+1,putchar('-');
11         do{ch[len++]=x%10+(1<<5)+(1<<4);x/=10;}while(x);
12         for(int i=len-1;i>=0;--i)putchar(ch[i]);putchar(opt);}
13 }using namespace AE86;
14 const int NN=1e6+5,inf=1e10;
15 int n,ans[NN],mid,p,q,s[NN];
16 bool vis[NN];
17 multiset<int> st;
18 priority_queue<int> a,b;
19 inline void push(int s){
20     if(!a.size() || s<=a.top()) a.push(s);
21     else b.push(-s);
22     if(a.size()<b.size()) a.push(-b.top()),b.pop();
23     if(a.size()>b.size()+1) b.push(-a.top()),a.pop();
24 }
25 namespace WSN{
26     inline short main(){
27         freopen("d.in","r",stdin);
28         freopen("d.out","w",stdout);
29         n=read(); mid=1+n>>1;
30         for(int i=1;i<=n;i++) s[i]=read();
31         sort(s+1,s+n+1);
32         if(s[mid]==s[mid+1]){
33             while(s[mid]==s[mid+1] && mid<n) ++mid;
34             write(s[mid],' '); p=mid-1; q=n;
35             while(p || mid<q){
36                 if(p) write(s[p--],' ');
37                 if(mid<q) write(s[q--],' ');
38             } return 0;
39         }
40         while(s[mid]!=s[mid-1] && mid>1) --mid;
41         write(s[mid],' '); vis[mid]=1; p=mid-1; q=n;
42         while(p && mid<q){
43             write(s[p],' '); vis[p--]=1;
44             write(s[q],' '); vis[q--]=1;
45         }
46         for(int i=1;i<=n;i++) if(vis[i]) push(s[i]);else st.insert(s[i]);
47         while(st.size()){
48             p=*st.begin();
49             if(a.size()==b.size()){
50                 if(p>=-b.top()) q=*--st.end();
51                 else q=*st.begin();
52             }
53             else{
54                 if(!b.empty() && p*2>=a.top()-b.top()) q=*--st.end();
55                 else q=*--st.upper_bound(p*2-a.top());
56             }
57             write(q,' '); push(q); st.erase(st.find(q));
58         }
59         return 0;
60     }
61 }
62 signed main(){return WSN::main();}
View Code

 

posted @ 2021-09-27 06:32  雪域亡魂  阅读(82)  评论(0编辑  收藏  举报