SHOI2019旅游记
题外话
为什么不更ZJOI day1的游记呢。。。。
因为考挂自闭了不想更。等day2考完再说咕咕咕
还是更个SHOI旅游记吧!反正不是自家省选,玩得真开心~~~
day0
SH好热好热啊,感觉到夏天了
day1
考场是一个奇怪的科技中心什么的,早上很早去本来以为要试机,后来发现考场都进不去。
进去了竟然说随便坐。。。我原来那个位置键盘贼难受,后来换了一个鼠标很诡异的位置,不过键盘还挺好用的。
SH还是发了面包,比ZJ优秀(???)午饭感觉也还不错的说
暴力60+40+?
T1是送的,T2是个后缀树模板,T3是个没意思的找规律。
T1其实不用“超级钢琴”也能做,二分出第k大的值顺便暴力枚举>k的求异或和。至于多log的话,把二分改成逐位确定就可以省掉那个log。在下代码力弱得没调出来,结果60分排序比较器写成了greater<int>(),于是就爆零了,哭(赛后loj快榜上目前还是rk1 upd:好吧xj大佬们切掉这题以后我瞬间被打爆了。。);我一开始题还读错了,读成了不相交区间,据说有人按照这个写拿了60。。。
T2大概认真学习过后缀树相关肯定能做出来,大概用到了后缀树上倍增定位+拆点建图。我大概没有学好后缀树,暴力又写挂了。
T3考脑洞和打表功底(出题人被喷了)。我玩了25,类型2根本看不出来,赛后恍然大悟QAQ
得分0+10+25,垫底了
讲课期间:
zjc: 我T2第三个大样例没过,拿了50分;刚刚有人说他三个样例都过了,他几分啊?我看看。。。(翻榜)诶他怎么0分啊
day2
暴力70+60+?
T1是dp,70是暴力dp加k=0的部分分,k=0是两部分分开dp(互相独立)。正解大概就是再优化一下,有限制的情况暴力跑,无限制的用k=0的方法跑。听说km^2会被卡常。
T2是贪心,感觉也是送的?大家好像都会做(只有我拿不到送的分)。链的部分分是个简单贪心,提示正解,正解就是套用链的做法把子树合并起来即可。
T3融合了很多知识点,包括树上连通块边数-点数=1算贡献,树形dp,长链剖分,数据结构等等,现在还没有搞太懂,据说其中一份std写了908行。反正十分毒瘤就是了。我写了大暴力加L=n,k=1的部分分得了20。
得分70+60+20,其实T3估分是24。。。不过挂4分也不想管他了。
upd: 丢失4分原因竟是数组开小。。。。。哭了。
讲课期间:
讲课人:我也是刚刚拿到ppt……(陷入僵局)
(过了一会儿)
讲课人:我们请AC的选手上来讲一下吧!
(过了一会儿,讲T3)
讲课人:我们请最高分选手上来讲一下吧!
(然后放了几页ppt,莫名其妙就结束了讲课)
总结
这个分数尤其day1的得分,总觉得是不太符合自己水平的分数。
虽然一次次考试结果证明自己真的很弱,根本跟不上大家的脚步,每次考试都是那种,总想要飞上天反而摔得粉身碎骨的感觉,正解不会写暴力还统统写挂。
不过自我安慰一下这次就是来玩玩的,反正考挂也没有什么影响,还是非常开心地浪了两天半~~~ QAQ
可惜的是noip实在太烂了连去北京浪的机会都没有,thupc感觉也审不过的吧。
noip。。。真的是一时疏忽,如今算是尝到恶果了。感觉真的只能滚去准备学考了啊。ZJOI二试,可能也要变成旅游了。
等明年吧。不甘心。
upd:放一下我AC的代码
1 #include<bits/stdc++.h> 2 #define rep(i,x,y) for (int i=(x);i<=(y);i++) 3 #define ll long long 4 5 using namespace std; 6 7 const int N=5e5+100; 8 int n,m,c[N*32][2],w[N*32],leaf[N*32],p[N],tot=1; ll a[N],sum[N],num[N],ans; 9 10 void ins(ll x){ 11 int now=1; 12 for (int i=31;~i;i--){ 13 int b=x>>i&1; 14 if (!c[now][b]) c[now][b]=++tot; 15 now=c[now][b],w[now]++; 16 } 17 leaf[now]++; 18 } 19 20 void dfs(int u,int i,ll x,ll y){ 21 if (!u||i<0||!w[u]) return; 22 if (leaf[u]) ans+=leaf[u]*(x^y); 23 dfs(c[u][0],i-1,x,y); 24 dfs(c[u][1],i-1,x|(1<<i-1),y); 25 } 26 27 int main(){ 28 scanf("%d%d",&n,&m); 29 rep (i,1,n) scanf("%lld",&a[i]),sum[i]=sum[i-1]^a[i]; 30 rep (i,0,n) ins(sum[i]),p[i]=1; 31 m*=2; ll res=0; 32 for (int i=31;~i;i--){ 33 ll s=0; 34 rep (j,0,n){ 35 ll b=sum[j]>>i&1; s+=w[c[p[j]][b^1]]; 36 } 37 if (s<m){ 38 m-=s; 39 rep (j,0,n){ 40 ll b=sum[j]>>i&1; 41 dfs(c[p[j]][b^1],i,num[j]|((b^1)<<i),sum[j]); 42 p[j]=c[p[j]][b],num[j]|=b<<i; 43 } 44 } else{ 45 res|=1ll<<i; 46 rep (j,0,n){ 47 ll b=sum[j]>>i&1; p[j]=c[p[j]][b^1],num[j]|=(b^1)<<i; 48 } 49 } 50 } 51 ans+=(ll)m*res; 52 printf("%lld\n",ans>>1); 53 return 0; 54 }
1 #include<bits/stdc++.h> 2 #define rep(i,x,y) for (int i=(x);i<=(y);i++) 3 #define pii pair<int,int> 4 #define fi first 5 #define se second 6 #define Vp vector<pii> 7 #define ll long long 8 9 using namespace std; 10 11 const int N=2000010; 12 int n,na,nb,Q,fa[N],ch[N][30],len[N],pos[N],tot,las,f[N][22],id[N]; Vp V[N]; 13 int cnt,head[N],val[N],num,q[N],rd[N]; 14 ll dp[N],ans; char s[N]; 15 struct edge{int to,nxt;}e[N<<1]; 16 17 void adde(int x,int y){ 18 e[++cnt].to=y; e[cnt].nxt=head[x]; head[x]=cnt; rd[y]++; 19 } 20 21 void sam_init(){ 22 rep (i,1,tot){ 23 memset(ch[i],0,sizeof(ch[i])), 24 memset(f[i],0,sizeof(f[i])),fa[i]=len[i]=0; 25 } 26 tot=las=1; 27 } 28 void extend(int c,int i){ 29 int p=las,np=las=++tot,q,nq; 30 len[np]=len[p]+1,pos[i]=np; 31 for (;p&&!ch[p][c];p=fa[p]) ch[p][c]=np; 32 if (!p){fa[np]=1; return;} 33 q=ch[p][c]; 34 if (len[p]+1==len[q]) fa[np]=q; 35 else{ 36 nq=++tot; len[nq]=len[p]+1; 37 memcpy(ch[nq],ch[q],sizeof(ch[q])); 38 fa[nq]=fa[q]; fa[q]=fa[np]=nq; 39 for (;p&&ch[p][c]==q;p=fa[p]) ch[p][c]=nq; 40 } 41 } 42 void tree_build(){ 43 rep (i,1,tot) f[i][0]=fa[i]; 44 rep (j,1,19) rep (i,1,tot) f[i][j]=f[f[i][j-1]][j-1]; 45 } 46 47 void get_node(int l,int r,int id){ 48 int x=pos[l]; 49 for (int i=19;~i;i--) 50 if (f[x][i]&&len[f[x][i]]>=r-l+1) x=f[x][i]; 51 V[x].push_back(pii(r-l+1,id)); 52 } 53 54 const bool cmp(pii x,pii y){ 55 return x.fi!=y.fi?x.fi<y.fi:x.se>y.se; 56 } 57 void graph_build(){ 58 rep (i,1,tot){ 59 sort(V[i].begin(),V[i].end(),cmp); 60 int sz=V[i].size(); 61 rep (j,0,sz-1){ 62 int x=V[i][j].se+2*tot; id[x-2*tot]=x; 63 if (!j) adde(i,x); 64 if (j<sz-1) adde(x,V[i][j+1].se+2*tot); else adde(x,i+tot); 65 if (x<=na+2*tot){ //A类点有贡献 66 id[x-2*tot]=++num; 67 adde(x,num),val[num]=V[i][j].fi; 68 } 69 } 70 if (!sz) adde(i,i+tot); 71 if (fa[i]) adde(fa[i]+tot,i); 72 } 73 } 74 void topo(){ 75 int h=1,t=0; 76 rep (i,1,num) if (!rd[i]) q[++t]=i,dp[i]=val[i]; 77 ans=0; 78 int tmp=0; 79 while (h<=t){ 80 int u=q[h++]; tmp++; 81 if (u>2*tot+na+nb) ans=max(ans,dp[u]); 82 for (int i=head[u],v;i;i=e[i].nxt){ 83 v=e[i].to; 84 if (!--rd[v]) q[++t]=v; 85 dp[v]=max(dp[v],dp[u]+val[v]); 86 } 87 } 88 if (t!=num) puts("-1"); else printf("%lld\n",ans); 89 } 90 91 int Main(){ 92 scanf("%s",s+1),n=strlen(s+1); sam_init(); 93 for (int i=n;i;i--) extend(s[i]-'a',i); tree_build(); 94 scanf("%d",&na); 95 rep (i,1,na){int l,r; scanf("%d%d",&l,&r),get_node(l,r,i);} 96 scanf("%d",&nb); 97 rep (i,1,nb){int l,r; scanf("%d%d",&l,&r),get_node(l,r,i+na);} 98 num=na+nb+2*tot; 99 graph_build(); 100 scanf("%d",&Q); 101 rep (i,1,Q){int x,y; scanf("%d%d",&x,&y),adde(id[x],id[y+na]);} 102 topo(); 103 rep (i,1,tot) V[i].clear(); 104 rep (i,1,num) head[i]=dp[i]=val[i]=rd[i]=0; cnt=0; 105 return 0; 106 } 107 108 int main(){ 109 int T; scanf("%d",&T); while (T--) Main(); 110 return 0; 111 }
#include<bits/stdc++.h> #define rep(i,x,y) for (int i=(x);i<=(y);i++) #define Vi vector<int> #define ll long long using namespace std; const int N=1010,M=2510,mod=998244353; int n,m,Q,c0,c1,d0,d1,a[N],bl[N],sum[N],ban[N],ban_c[N],all,lx,rx,ly,ry,Sz,Nowsz; int f[2][M][M],g[N][M],ans,fx[M],fy[M],dp0[M][M],dp1[M][M]; Vi v[N]; void upd(int &x,int y){x+=y; x-=x>=mod?mod:0;} void dp(int x,int st){ int sz=v[x].size(),tmp,nowsz=0; rep (i,0,sz) rep (j,0,Nowsz) g[i][j]=0; g[0][0]=1; rep (i,0,sz-1){ int y=v[x][i]; if (!ban[y]){ rep (j,0,nowsz) g[i+1][j]=g[i][j]; continue; } rep (j,0,nowsz) if (tmp=g[i][j]){ if (ban[y]!=st&&j+a[y]<=d0) upd(g[i+1][j+a[y]],tmp); if (ban[y]!=st+1) upd(g[i+1][j],tmp); } nowsz+=a[y]; nowsz=min(nowsz,d0); } } int Main(){ scanf("%d%d%d%d%d%d",&n,&m,&c0,&c1,&d0,&d1); all=0; rep (i,1,n){ int x,y; scanf("%d%d",&x,&y); v[x].push_back(i),sum[x]+=y,a[i]=y,all+=y,bl[i]=x; } scanf("%d",&Q); rep (i,1,Q){ int x,y; scanf("%d%d",&x,&y); ban[x]=y+1,ban_c[bl[x]]=1; } lx=all-c1,rx=c0,ly=all-d1,ry=d0; if (lx>rx||ly>ry){ rep (i,1,m) v[i].clear(),sum[i]=0; rep (i,1,n) ban[i]=a[i]=0; return puts("0"),0; } memset(fx,0,sizeof(fx)),memset(fy,0,sizeof(fy)); fx[0]=fy[0]=1; rep (i,1,m) if (!ban_c[i]&&sum[i]) for (int j=c0;j>=sum[i];j--) upd(fx[j],fx[j-sum[i]]); rep (i,1,n) if (!ban[i]) for (int j=d0;j>=a[i];j--) upd(fy[j],fy[j-a[i]]); rep (i,0,c0) rep (j,0,d0) dp0[i][j]=(ll)fx[i]*fy[j]%mod; int now=0; memset(f[now],0,sizeof(f[now])); f[0][0][0]=1; rep (i,0,m-1) if (ban_c[i+1]){ now^=1; rep (j,0,c0) rep (k,0,Sz) f[now][j][k]=0; int sz=v[i+1].size(); if (!sz){ rep (j,0,c0) rep (k,0,Sz) f[now][j][k]=f[now^1][j][k]; continue; } int nowsz=0; rep (j,0,sz-1) if (ban[v[i+1][j]]) nowsz+=a[v[i+1][j]]; nowsz=min(nowsz,d0); Nowsz=nowsz; rep (j,0,c0){ if (j+sum[i+1]<=c0){ dp(i+1,1); rep (k,0,Sz) if (f[now^1][j][k]) rep (l,0,min(d0-k,nowsz)) if (g[sz][l]) upd(f[now][j+sum[i+1]][k+l],(ll)f[now^1][j][k]*g[sz][l]%mod); } dp(i+1,3); rep (k,0,Sz) if (f[now^1][j][k]) rep (l,0,min(d0-k,nowsz)) if (g[sz][l]) upd(f[now][j][k+l],(ll)f[now^1][j][k]*g[sz][l]%mod); } Sz+=nowsz,Sz=min(Sz,d0); } rep (i,0,c0) rep (j,0,d0){ dp1[i][j]=f[now][i][j]; if (i) upd(dp1[i][j],dp1[i-1][j]); if (j) upd(dp1[i][j],dp1[i][j-1]); if (i&&j) upd(dp1[i][j],mod-dp1[i-1][j-1]); } ans=0; rep (i,0,c0) rep (j,0,d0){ int Lx=max(lx-i,0),Rx=rx-i; int Ly=max(ly-j,0),Ry=ry-j; if (Lx>Rx||Ly>Ry) continue; int s=dp1[Rx][Ry]; if (Lx) upd(s,mod-dp1[Lx-1][Ry]); if (Ly) upd(s,mod-dp1[Rx][Ly-1]); if (Lx&&Ly) upd(s,dp1[Lx-1][Ly-1]); upd(ans,(ll)s*dp0[i][j]%mod); } printf("%d\n",ans); rep (i,1,m) v[i].clear(),sum[i]=0; rep (i,1,n) ban[i]=a[i]=0; return 0; } int main(){ int T; scanf("%d",&T); while (T--) Main(); return 0; }
1 #include<bits/stdc++.h> 2 #define rep(i,x,y) for (int i=(x);i<=(y);i++) 3 #define Vi vector<int> 4 #define ll long long 5 6 using namespace std; 7 8 const int N=2e5+10; 9 int n,cnt,head[N],a[N],fa[N],id[N]; ll ans; priority_queue<int> q[N]; 10 struct edge{int to,nxt;}e[N<<1]; 11 12 void adde(int x,int y){ 13 e[++cnt].to=y; e[cnt].nxt=head[x]; head[x]=cnt; 14 } 15 16 priority_queue<int> c; 17 void merge(priority_queue<int> &a,priority_queue<int> &b){ 18 if (a.size()<b.size()) swap(a,b); 19 while (!c.empty()) c.pop(); 20 while (!b.empty()){ 21 int x=max(a.top(),b.top()); 22 a.pop(),b.pop(),c.push(x); 23 } 24 while (!c.empty()) a.push(c.top()),c.pop(); 25 } 26 27 void dfs(int u){ 28 for (int i=head[u];i;i=e[i].nxt) dfs(e[i].to); 29 for (int i=head[u];i;i=e[i].nxt) merge(q[u],q[e[i].to]); 30 q[u].push(a[u]); 31 } 32 33 int main(){ 34 scanf("%d",&n); 35 rep (i,1,n) scanf("%d",&a[i]); 36 rep (i,2,n) scanf("%d",&fa[i]),adde(fa[i],i); 37 dfs(1); 38 while (!q[1].empty()) ans+=q[1].top(),q[1].pop(); 39 printf("%lld\n",ans); 40 return 0; 41 }