1. 程式人生 > 其它 >Noip模擬72 2021.10.9

Noip模擬72 2021.10.9

T1 出了個大陰間題 T2 最簡單辣快來做 T3 是我的不要搶 T4 顯然也是我整的

T1 出了個大陰間題

真就以為他出了個大陰間題就沒寫,打個暴力就跑了

資料範圍顯然擺明是狀壓

設$f[sta][0/1]$表示在已經選擇的集合$sta$中,$A$的最大值是$A$還是$A+1$

然後按照轉移之後的集合內的最大值當前集合的最大值的關係分情況轉移,(這裡的最大值不是$A$的最大值,是原數的最大值)

所以預處理一個集合內最大值的陣列,轉移可以達到$O(2^n n)$

 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(register int i=len-1;i>=0;--i)putchar(ch[i]);putchar(opt);} 13 }using namespace AE86; 14 const int NN=19,mod=1e9+7; 15 int n,k,a[NN],smx[1<<NN]; 16 struct dp{int num,B,sum;}f[1
<<19][2]; 17 namespace WSN{ 18 inline short main(){ 19 freopen("repair.in","r",stdin); freopen("repair.out","w",stdout); 20 n=read(); k=read(); int U=(1<<n)-1; 21 for(int i=1;i<=n;i++) a[i]=read(); 22 for(int i=1;i<=U;i++) for(int j=1;j<=n;j++) 23 if(i&(1<<j-1)) smx[i]=max(smx[i],a[j]); 24 for(int i=0;i<n;i++) f[1<<i][0].num=1; 25 for(int i=1;i<=U;i++) for(int j=1;j<=n;j++) if(!(i&(1<<j-1))){ 26 int to=i|(1<<j-1); 27 if(smx[to]==smx[i]&&smx[to]==a[j]){ 28 if(f[i][0].num){ 29 (f[to][1].num+=f[i][0].num)%=mod; 30 (f[to][1].B+=2*f[i][0].B%mod+f[i][0].num)%=mod; 31 (f[to][1].sum+=f[i][0].B+f[i][0].sum+f[i][0].num*k%mod*(smx[to]+1)%mod)%=mod; 32 } 33 if(f[i][1].num){ 34 (f[to][1].num+=f[i][1].num)%=mod; 35 (f[to][1].B+=2*f[i][1].B%mod+f[i][1].num)%=mod; 36 (f[to][1].sum+=f[i][1].B+f[i][1].sum+f[i][1].num*k%mod*(smx[to]+1)%mod)%=mod; 37 } 38 }else if(smx[to]==smx[i]+1||smx[to]==smx[i]){ 39 if(f[i][0].num){ 40 (f[to][0].num+=f[i][0].num)%=mod; 41 (f[to][0].B+=2*f[i][0].B%mod+f[i][0].num)%=mod; 42 (f[to][0].sum+=f[i][0].B+f[i][0].sum+f[i][0].num*k%mod*smx[to]%mod)%=mod; 43 } 44 if(f[i][1].num){ 45 (f[to][1].num+=f[i][1].num)%=mod; 46 (f[to][1].B+=2*f[i][1].B%mod+f[i][1].num)%=mod; 47 (f[to][1].sum+=f[i][1].B+f[i][1].sum+f[i][1].num*k%mod*(smx[to]+1)%mod)%=mod; 48 } 49 } 50 else{ 51 if(f[i][0].num){ 52 (f[to][0].num+=f[i][0].num)%=mod; 53 (f[to][0].B+=2*f[i][0].B%mod+f[i][0].num)%=mod; 54 (f[to][0].sum+=f[i][0].B+f[i][0].sum+f[i][0].num*k%mod*smx[to]%mod)%=mod; 55 } 56 if(f[i][1].num){ 57 (f[to][0].num+=f[i][1].num)%=mod; 58 (f[to][0].B+=2*f[i][1].B%mod+f[i][1].num)%=mod; 59 (f[to][0].sum+=f[i][1].B+f[i][1].sum+f[i][1].num*k%mod*smx[to]%mod)%=mod; 60 } 61 } 62 } 63 if(f[U][1].num) write(smx[U]+1,' '),write(f[U][1].sum); 64 else write(smx[U],' '),write(f[U][0].sum); 65 return 0; 66 } 67 } 68 signed main(){return WSN::main();}
View Code

T2 最簡單辣快來做

說的挺簡單,除了$T4$這個最難

看見絕對值就給他拆開絕對錯不了,然後考慮四個方向統計貢獻

比較妙的按照每一個點的$x,y$把原來的圖分成$(n+1)^2$個小矩形,注意離散化

然後統計字首和,這裡的字首和是指從一個格點到另一個格點需要的代價,是$a^i , b^j$的貢獻,不是單純的加和

處理完之後每次詢問就可以$log(n)$的複雜度計算了,注意不想卡常的話使用光速冪,是一種類似分塊的思想

可以做到$O(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(register int i=len-1;i>=0;--i)putchar(ch[i]);putchar(opt);}
12 }using namespace AE86;
13 const int NN=2005;
14 int n,q,w,h,mod,a,b,dis1[NN],dis2[NN];
15 struct sate{int h,x,y;}s[NN];
16 int sum[NN][NN][5];
17 inline int mo(int x){return x>=mod?x-mod:x;}
18 namespace gsm{
19     const int KK=1e5+5;
20     int bl,A[KK],B[KK],pwa[KK],pwb[KK],k,r,res;
21     inline void init(){
22         A[0]=B[0]=pwa[0]=pwb[0]=1;
23         bl=ceil(sqrt(1.0*max(w,h)));
24         for(int i=1;i<=bl;i++){
25             A[i]=1ll*A[i-1]*a%mod;
26             B[i]=1ll*B[i-1]*b%mod;
27         }
28         for(int i=1;i<=bl;i++){
29             pwa[i]=1ll*pwa[i-1]*A[bl]%mod;
30             pwb[i]=1ll*pwb[i-1]*B[bl]%mod;
31         }
32     }
33     inline int qmo(int x,int b){
34         // cout<<x<<" "<<b<<endl;
35         if(b<0) return 0; k=b/bl; r=b%bl;
36         if(x==a) res=1ll*pwa[k]*A[r]%mod;
37         else res=1ll*pwb[k]*B[r]%mod;
38         return res;
39     }
40 }using namespace gsm;
41 inline void discrete(){
42     sort(dis1+1,dis1+n+1); sort(dis2+1,dis2+n+1);
43     for(int i=1;i<=n;++i)s[i].x=lower_bound(dis1+1,dis1+n+1,s[i].x)-dis1;
44     for(int i=1;i<=n;++i)s[i].y=lower_bound(dis2+1,dis2+n+1,s[i].y)-dis2;
45 }
46 namespace WSN{
47     inline short main(){
48         // freopen("in.in","r",stdin); //freopen("bao.out","w",stdout);
49         freopen("satellite.in","r",stdin); freopen("satellite.out","w",stdout);
50         n=read();q=read();w=read();h=read();mod=read();a=read();b=read();
51         for(int i=1;i<=n;++i) s[i].h=read(),dis1[i]=s[i].x=read(),dis2[i]=s[i].y=read();
52         discrete(); init();
53         for(int i=1;i<=n;++i)
54             sum[s[i].x][s[i].y][1]=sum[s[i].x][s[i].y][2]=sum[s[i].x][s[i].y][3]=sum[s[i].x][s[i].y][4]=s[i].h;
55         
56         for(int i=1;i<=n;++i){
57             for(int j=1;j<=n;++j) sum[i][j][1]=mo(sum[i][j][1]+1ll*sum[i][j-1][1]*qmo(b,dis2[j]-dis2[j-1])%mod);
58             for(int j=1;j<=n;++j) sum[i][j][1]=mo(sum[i][j][1]+1ll*sum[i-1][j][1]*qmo(a,dis1[i]-dis1[i-1])%mod);
59             for(int j=n;j;--j)    sum[i][j][3]=mo(sum[i][j][3]+1ll*sum[i][j+1][3]*qmo(b,dis2[j+1]-dis2[j])%mod);
60             for(int j=n;j;--j)    sum[i][j][3]=mo(sum[i][j][3]+1ll*sum[i-1][j][3]*qmo(a,dis1[i]-dis1[i-1])%mod);
61         }
62         for(int i=n;i;--i){
63             for(int j=1;j<=n;++j) sum[i][j][2]=mo(sum[i][j][2]+1ll*sum[i][j-1][2]*qmo(b,dis2[j]-dis2[j-1])%mod);
64             for(int j=1;j<=n;++j) sum[i][j][2]=mo(sum[i][j][2]+1ll*sum[i+1][j][2]*qmo(a,dis1[i+1]-dis1[i])%mod);
65             for(int j=n;j;--j)    sum[i][j][4]=mo(sum[i][j][4]+1ll*sum[i][j+1][4]*qmo(b,dis2[j+1]-dis2[j])%mod);
66             for(int j=n;j;--j)    sum[i][j][4]=mo(sum[i][j][4]+1ll*sum[i+1][j][4]*qmo(a,dis1[i+1]-dis1[i])%mod);
67         }
68         int qx,qy,X,Y,x1,x2,y1,y2,tmp;
69         for(int o=1;o<=q;++o){
70             qx=read(),qy=read(),X,Y;
71             X=lower_bound(dis1+1,dis1+n+1,qx)-dis1;
72             Y=lower_bound(dis2+1,dis2+n+1,qy)-dis2;
73             x1=X-1,x2=X,y1=Y-1,y2=Y,tmp=0;
74                              tmp=mo(tmp+1ll*sum[x1][y1][1]*qmo(b,qy-dis2[y1])%mod*qmo(a,qx-dis1[x1])%mod);
75             if(x2<=n)          tmp=mo(tmp+1ll*sum[x2][y1][2]*qmo(b,qy-dis2[y1])%mod*qmo(a,dis1[x2]-qx)%mod);
76             if(y2<=n)          tmp=mo(tmp+1ll*sum[x1][y2][3]*qmo(b,dis2[y2]-qy)%mod*qmo(a,qx-dis1[x1])%mod);
77             if(y2<=n&&x2<=n) tmp=mo(tmp+1ll*sum[x2][y2][4]*qmo(b,dis2[y2]-qy)%mod*qmo(a,dis1[x2]-qx)%mod);
78             write(tmp);
79         }
80         return 0;
81     }
82 }
83 signed main(){return WSN::main();}
View Code

T3 是我的你不要搶

$hash$,$cao$過去就完了....

考試的時候字串就用$hash$,別瞎搞什麼$kmp$難想還難調

當時先想了個二分,非常假,我太傻。。。

後來就不知道哪裡來的勇氣碼$kmp$,然後還是假,因為$bouder$的性質假的

其實直接拿$vector$存$hash$值然後生猛列舉匹配長度,再拿$map$存一下答案記憶化就可以水掉了

這麼簡單的思路,考場上沉迷看毛片無法自拔沒想到,非常後悔,但是這道題的特殊性正好適應了這種無腦的暴力

造的最極限的資料不開$O2$卡到了九秒,開了$O2$就跑$1.4$,非常不懂

 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(register int i=len-1;i>=0;--i)putchar(ch[i]);putchar(opt);}
13 }using namespace AE86;
14 typedef unsigned long long ULL;
15 const ULL base=131;
16 const int NN=6e5+5;
17 int n,q,len[NN];
18 char ch[NN];
19 ULL pw[NN];
20 vector<ULL> ha[NN];
21 map<pair<int,int>,int> mp;
22 inline void task(){
23     scanf("%s",ch+1);int l=strlen(ch+1);
24     while(q--){int x=read(),y=read();write(l);}
25 }
26 inline ULL get(int i,int l,int r){
27     return ha[i][r]-ha[i][l-1]*pw[r-l+1];
28 }
29 namespace WSN{
30     inline short main(){
31         // freopen("in.in","r",stdin); freopen("bao.out","w",stdout);
32         freopen("string.in","r",stdin); freopen("string.out","w",stdout);
33         n=read();q=read(); if(n==1) return task(),0;
34         pw[0]=1; for(int i=1;i<NN;++i) pw[i]=pw[i-1]*base;
35         for(int i=1;i<=n;++i){
36             scanf("%s",ch+1);len[i]=strlen(ch+1);ha[i].push_back(0);
37             for(int j=1;j<=len[i];++j){
38                 ULL last=ha[i].back();
39                 ha[i].push_back(last*base+(ULL)(ch[j]-'a'+1));
40             }
41         }
42         for(int o=1;o<=q;++o){
43             int x=read(),y=read();
44             if(mp.find(make_pair(x,y))!=mp.end()){
45                 write(mp[make_pair(x,y)]);continue;
46             }
47             bool flag=0;int l=min(len[x],len[y]);
48             for(int i=l;i;--i)
49                 if(get(x,len[x]-i+1,len[x])==get(y,1,i)){
50                     write(i);mp[make_pair(x,y)]=i;flag=1;break;
51                 }
52             if(!flag) puts("0"),mp[make_pair(x,y)]=0;
53         }
54         return 0;
55     }
56 }
57 signed main(){return WSN::main();}
View Code

T4 顯然也是我咕的