TJOI2018
好像被老张坑了,TJ省选怎么出六道送分题啊。。。。。
d1t1[TJOI2018]数学计算
线段树模板题。
//Achen
#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<vector>
#include<cstdio>
#include<queue>
#include<cmath>
#include<set>
#include<map>
#define For(i,a,b) for(int i=(a);i<=(b);i++)
#define Rep(i,a,b) for(int i=(a);i>=(b);i--)
const int N=100007;
typedef long long LL;
typedef double db;
using namespace std;
int T,Q,mod;
template<typename T> void read(T &x) {
char ch=getchar(); x=0; T f=1;
while(ch!='-'&&(ch<'0'||ch>'9')) ch=getchar();
if(ch=='-') f=-1,ch=getchar();
for(;ch>='0'&&ch<='9';ch=getchar()) x=x*10+ch-'0'; x*=f;
}
#define lc x<<1
#define rc ((x<<1)|1)
#define mid ((l+r)>>1)
LL sg[N<<2];
void build(int x,int l,int r) {
sg[x]=1; if(l==r) return ;
build(lc,l,mid); build(rc,mid+1,r);
}
void update(int x,int l,int r,int pos,LL v) {
if(l==r) { sg[x]=v; return; }
if(pos<=mid) update(lc,l,mid,pos,v);
else update(rc,mid+1,r,pos,v);
sg[x]=sg[lc]*sg[rc]%mod;
}
//#define DEBUG
int main() {
#ifdef DEBUG
freopen("1.in","r",stdin);
//freopen(".out","w",stdout);
#endif
read(T);
while(T--) {
read(Q); read(mod);
build(1,1,Q);
For(ti,1,Q) {
int o,pos; LL m;
read(o);
if(o==1) {
read(m);
update(1,1,Q,ti,m%mod);
printf("%lld\n",sg[1]);
}
else {
read(pos);
update(1,1,Q,pos,1);
printf("%lld\n",sg[1]);
}
}
}
return 0;
}
d1t2[TJOI2018]智力竞赛
二分答案,把值小于二分的答案的点拿出来跑匈牙利,注意若两个小于二分答案的点之间可以通过一坨大于二分答案的点相连,那这两个点之间也要连边,可以用拓扑排序来连这种边。
1 //Achen
2 #include<algorithm>
3 #include<iostream>
4 #include<cstring>
5 #include<cstdlib>
6 #include<vector>
7 #include<cstdio>
8 #include<queue>
9 #include<cmath>
10 #include<set>
11 #include<map>
12 #define For(i,a,b) for(int i=(a);i<=(b);i++)
13 #define Rep(i,a,b) for(int i=(a);i>=(b);i--)
14 const int N=507;
15 typedef long long LL;
16 typedef double db;
17 using namespace std;
18 int n,m,ls[N],v[N];
19
20 template<typename T> void read(T &x) {
21 char ch=getchar(); x=0; T f=1;
22 while(ch!='-'&&(ch<'0'||ch>'9')) ch=getchar();
23 if(ch=='-') f=-1,ch=getchar();
24 for(;ch>='0'&&ch<='9';ch=getchar()) x=x*10+ch-'0'; x*=f;
25 }
26
27
28 struct hungary{
29 int ecnt,fir[N],nxt[N*N],to[N*N],vis[N],pr[N];;
30
31 void init() {
32 memset(fir,0,sizeof(fir));
33 memset(pr,0,sizeof(pr));
34 ecnt=0;
35 }
36
37 void add(int u,int v) {
38 nxt[++ecnt]=fir[u]; fir[u]=ecnt; to[ecnt]=v;
39 }
40
41 int find(int u) {
42 for(int i=fir[u];i;i=nxt[i]) if(!vis[to[i]]) {
43 vis[to[i]]=1;
44 if(!pr[to[i]]||find(pr[to[i]])) {
45 pr[to[i]]=u;
46 return 1;
47 }
48 }
49 return 0;
50 }
51
52 int ck(int w) {
53 int rs=0;
54 For(i,1,m) if(v[i]<w) {
55 memset(vis,0,sizeof(vis));
56 if(!find(i)) rs++;
57 if(rs>n) return 0;
58 }
59 return 1;
60 }
61
62 }H;
63
64 struct solve{
65 int ecnt,fir[N],nxt[N*N],to[N*N],in[N],tpin[N];
66 void add(int u,int v) {
67 nxt[++ecnt]=fir[u]; fir[u]=ecnt; to[ecnt]=v; in[v]++;
68 }
69
70 vector<int>vc[N];
71 queue<int>que;
72 void tpsort(int w) {
73 For(i,1,m) in[i]=tpin[i],vc[i].clear();
74 For(i,1,m) if(!in[i]) {
75 que.push(i);
76 if(v[i]<w) vc[i].push_back(i);
77 }
78 while(!que.empty()) {
79 int x=que.front();
80 que.pop();
81 int up=vc[x].size();
82 for(int i=fir[x];i;i=nxt[i]) {
83 int y=to[i];
84 For(j,0,up-1) {
85 int z=vc[x][j];
86 if(v[y]<w) H.add(z,y);
87 else vc[y].push_back(z);
88 }
89 in[y]--;
90 if(!in[y]) {
91 que.push(y);
92 if(v[y]<w) vc[y].push_back(y);
93 }
94 }
95 }
96 }
97
98 void work() {
99 read(n); read(m); n++;
100 For(i,1,m) {
101 read(v[i]); ls[i]=v[i];
102 int k,y; read(k);
103 For(j,1,k) {
104 read(y); add(i,y); H.add(i,y);
105 }
106 }
107 For(i,1,m) tpin[i]=in[i];
108 sort(ls+1,ls+m+1);
109 if(H.ck(ls[m]+1)) { puts("AK"); return ;}
110 int l=1,r=m,ans=0;
111 while(l<=r) {
112 int mid=((l+r)>>1);
113 H.init();
114 tpsort(ls[mid]);
115 if(H.ck(ls[mid])) ans=ls[mid],l=mid+1;
116 else r=mid-1;
117 }
118 printf("%d\n",ans);
119 }
120 }S;
121
122 //#define DEBUG
123 int main() {
124 #ifdef DEBUG
125 freopen("1.in","r",stdin);
126 //freopen(".out","w",stdout);
127 #endif
128 S.work();
129 return 0;
130 }
d1t3[TJOI2018]游园会
这道题翻车了。。。其实是一道dp简单题。。。想了一中午然后只会打30分暴力。。。发现状态数算错了。。。我竟然以为g数组相邻两位可以相差大于1.。。。跑出了3e7那么多的状态。。。。
g[i]表示表示当前串和奖章串的前i位匹配的最长公共子序列,发现g的相邻两位差为1或0,那么把g差分后状压dp即可。
1 //Achen
2 #include<algorithm>
3 #include<iostream>
4 #include<cstring>
5 #include<cstdlib>
6 #include<vector>
7 #include<cstdio>
8 #include<queue>
9 #include<cmath>
10 #include<set>
11 #include<map>
12 #define For(i,a,b) for(int i=(a);i<=(b);i++)
13 #define Rep(i,a,b) for(int i=(a);i>=(b);i--)
14 const int N=1007,up=32768,mod=1e9+7;
15 typedef long long LL;
16 typedef double db;
17 using namespace std;
18 int n,k,o;
19 char S[20],t[5]={'N','N','O','I'};
20 LL f[2][up][4],ans[20],to[up][4];
21
22 template<typename T> void read(T &x) {
23 char ch=getchar(); x=0; T f=1;
24 while(ch!='-'&&(ch<'0'||ch>'9')) ch=getchar();
25 if(ch=='-') f=-1,ch=getchar();
26 for(;ch>='0'&&ch<='9';ch=getchar()) x=x*10+ch-'0'; x*=f;
27 }
28
29 int cg(int x,int y) {
30 if(y==x+1) return x+1;
31 else return y==1?1:0;
32 }
33
34 int g[20];
35 void pre(int nn) {
36 For(i,0,nn) For(l,1,3) {
37 For(j,0,k-1) {
38 g[j+1]=g[j];
39 if(i&(1<<j)) g[j+1]++;
40 }
41 Rep(j,k,1) {
42 if(S[j-1]==t[l]&&g[j]==g[j-1]) g[j]=g[j-1]+1;
43 }
44 For(j,1,k) {
45 g[j]=max(g[j],g[j-1]);
46 if(g[j]>g[j-1]) to[i][l]|=(1<<j-1);
47 }
48 }
49 }
50
51 //#define DEBUG
52 int main() {
53 #ifdef DEBUG
54 freopen("1.in","r",stdin);
55 //freopen(".out","w",stdout);
56 #endif
57 read(n); read(k);
58 scanf("%s",S);
59 int nn=(1<<k)-1;
60 pre(nn);
61 f[o][0][0]=1;
62 For(i,0,n-1) {
63 o^=1;
64 memset(f[o],0,sizeof(f[o]));
65 For(s,0,nn) For(j,0,2) if(f[o^1][s][j]) {
66 For(k,1,3) {
67 if(j==2&&k==3) continue;
68 (f[o][to[s][k]][cg(j,k)]+=f[o^1][s][j])%=mod;
69 }
70 }
71 }
72 For(i,0,nn) if(f[o][i][0]||f[o][i][1]||f[o][i][2]){
73 int tp=0;
74 For(j,0,k-1) if(i&(1<<j)) tp++;
75 (ans[tp]+=(f[o][i][0]+f[o][i][1]+f[o][i][2])%mod)%=mod;
76 }
77 For(i,0,k) printf("%lld\n",ans[i]);
78 return 0;
79 }
d2t1[TJOI2018]碱基序列
发现用kmp把每个小串跟大串匹配一遍复杂度够用,每一类串匹配的时候若匹配到的位置的上一位有上一类串的标记,就在匹配到的位置的结尾打上这一类的标记,同时计数,最后输出有第n类标记的点上的cnt即可。
//Achen
#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<vector>
#include<cstdio>
#include<queue>
#include<cmath>
#include<set>
#include<map>
#define For(i,a,b) for(int i=(a);i<=(b);i++)
#define Rep(i,a,b) for(int i=(a);i>=(b);i--)
const int mod=1000000007;
const int N=10007;
typedef long long LL;
typedef double db;
using namespace std;
int n,len;
char s[N],q[N];
template<typename T> void read(T &x) {
char ch=getchar(); x=0; T f=1;
while(ch!='-'&&(ch<'0'||ch>'9')) ch=getchar();
if(ch=='-') f=-1,ch=getchar();
for(;ch>='0'&&ch<='9';ch=getchar()) x=x*10+ch-'0'; x*=f;
}
int nxt[N];
void make_nxt() {
int l=strlen(q);
For(i,0,l) nxt[i]=0;
for(int i=1,k=0;i<l;i++) {
while(k&&q[i]!=q[k]) k=nxt[k-1];
if(q[i]==q[k]) k++;
nxt[i]=k;
}
}
int col[2][N],o;
LL cnt[2][N];
void make_tag(int id) {
int k=0;
int l=strlen(q);
For(i,0,len-1) {
while(k&&q[k]!=s[i]) k=nxt[k-1];
if(q[k]==s[i]) k++;
if(k==l) {
if(id==1||(i>=l&&col[o^1][i-l]==id-1)) {
if(col[o][i]==id) (cnt[o][i]+=cnt[o^1][max(0,i-l)])%=mod;
else { col[o][i]=id; cnt[o][i]=cnt[o^1][max(0,i-l)]; }
}
}
}
}
//#define DEBUG
int main() {
#ifdef DEBUG
freopen("std.in","r",stdin);
//freopen(".out","w",stdout);
#endif
read(n);
scanf("%s",s);
len=strlen(s);
For(i,0,len) cnt[o][i]=1;
For(i,1,n) {
o^=1;
int k; read(k);
For(j,1,k) {
scanf("%s",q);
make_nxt();
make_tag(i);
}
}
LL ans=0;
For(i,0,len-1) if(col[o][i]==n) (ans+=cnt[o][i])%=mod;
printf("%lld\n",ans);
return 0;
}
d2t2[TJOI2018]异或
用可持久化Trie即可解决所有问题。
1 //Achen
2 #include<algorithm>
3 #include<iostream>
4 #include<cstring>
5 #include<cstdlib>
6 #include<vector>
7 #include<cstdio>
8 #include<queue>
9 #include<cmath>
10 #include<set>
11 #include<map>
12 #define For(i,a,b) for(int i=(a);i<=(b);i++)
13 #define Rep(i,a,b) for(int i=(a);i>=(b);i--)
14 const int N=100007;
15 typedef long long LL;
16 typedef double db;
17 using namespace std;
18 int n,Q,cnt,tot;
19 LL val[N],ans[N],power[35];
20
21 template<typename T> void read(T &x) {
22 char ch=getchar(); x=0; T f=1;
23 while(ch!='-'&&(ch<'0'||ch>'9')) ch=getchar();
24 if(ch=='-') f=-1,ch=getchar();
25 for(;ch>='0'&&ch<='9';ch=getchar()) x=x*10+ch-'0'; x*=f;
26 }
27
28 struct node {
29 int id,y,z;
30 node(){}
31 node(int id,int y,int z):id(id),y(y),z(z){}
32 }p[N];
33 vector<node>vc[N];
34
35 int ecnt,fir[N],nxt[N<<1],to[N<<1];
36 void add(int u,int v) {
37 nxt[++ecnt]=fir[u]; fir[u]=ecnt; to[ecnt]=v;
38 nxt[++ecnt]=fir[v]; fir[v]=ecnt; to[ecnt]=u;
39 }
40
41 struct LCA {
42 int f[N][18],R[N];
43 void dfs(int x,int fa) {
44 f[x][0]=fa;
45 R[x]=R[fa]+1;
46 For(i,1,16) f[x][i]=f[f[x][i-1]][i-1];
47 for(int i=fir[x];i;i=nxt[i]) if(to[i]!=fa)
48 dfs(to[i],x);
49 }
50
51 int lca(int x,int y) {
52 if(R[x]<R[y]) swap(x,y);
53 Rep(i,16,0) if(R[f[x][i]]>=R[y])
54 x=f[x][i];
55 if(x==y) return x;
56 Rep(i,16,0) if(f[x][i]!=f[y][i])
57 x=f[x][i],y=f[y][i];
58 return f[x][0];
59 }
60 }L;
61
62 struct Trie {
63 int ch[N*100][2],sz[N*100],rt[N],tot;
64 void init() {
65 tot=0;
66 memset(rt,0,sizeof(rt));
67 memset(ch,0,sizeof(ch));
68 memset(sz,0,sizeof(sz));
69 }
70
71 void update(int &x,int last,int now,LL v) {
72 x=++tot;
73 sz[x]=sz[last]+1;
74 ch[x][0]=ch[last][0];
75 ch[x][1]=ch[last][1];
76 if(now<0) return ;
77 if(v&power[now]) update(ch[x][1],ch[last][1],now-1,v);
78 else update(ch[x][0],ch[last][0],now-1,v);
79 }
80
81 LL qry(int l,int r,int now,LL v) {
82 if(now<0) return 0;
83 if(v&power[now]) {
84 if(sz[ch[r][0]]-sz[ch[l][0]])
85 return qry(ch[l][0],ch[r][0],now-1,v)+power[now];
86 else return qry(ch[l][1],ch[r][1],now-1,v);
87 }
88 else {
89 if(sz[ch[r][1]]-sz[ch[l][1]])
90 return qry(ch[l][1],ch[r][1],now-1,v)+power[now];
91 else return qry(ch[l][0],ch[r][0],now-1,v);
92 }
93 }
94
95 }T;
96
97 struct work {
98 int dfn[N],tid[N],dfs_clock,sz[N];
99 void dfs(int x,int fa) {
100 dfn[x]=++dfs_clock;
101 tid[dfn[x]]=x;
102 sz[x]=1;
103 T.update(T.rt[x],T.rt[fa],30,val[x]);
104 int up=vc[x].size();
105 For(i,0,up-1) {
106 node tp=vc[x][i];
107 ans[tp.id]=max(ans[tp.id],T.qry(T.rt[tp.y],T.rt[x],30,tp.z));
108 }
109 for(int i=fir[x];i;i=nxt[i]) if(to[i]!=fa) {
110 dfs(to[i],x);
111 sz[x]+=sz[to[i]];
112 }
113 }
114
115 void solve2() {
116 T.init();
117 For(i,1,n)
118 T.update(T.rt[i],T.rt[i-1],30,val[tid[i]]);
119 For(i,1,cnt) {
120 node tp=p[i];
121 ans[tp.id]=max(ans[tp.id],T.qry(T.rt[dfn[tp.y]],T.rt[dfn[tp.y]+sz[tp.y]-1],30,tp.z));
122 }
123 }
124 }W;
125
126 //#define DEBUG
127 int main() {
128 #ifdef DEBUG
129 freopen("1.in","r",stdin);
130 //freopen(".out","w",stdout);
131 #endif
132 read(n); read(Q);
133 For(i,1,n) read(val[i]);
134 For(i,0,30) power[i]=(1LL<<i);
135 For(i,2,n) {
136 int x,y;
137 read(x); read(y);
138 add(x,y);
139 }
140 L.dfs(1,0);
141 For(i,1,Q) {
142 int o,x,y; LL z; read(o);
143 if(o==1) {
144 read(x); read(z);
145 ans[i]=(z^val[x]);
146 p[++cnt]=node(i,x,z);
147 }
148 else {
149 read(x); read(y); read(z);
150 int lca=L.lca(x,y);
151 if(x!=lca) vc[x].push_back(node(i,lca,z));
152 if(y!=lca) vc[y].push_back(node(i,lca,z));
153 ans[i]=(z^val[lca]);
154 }
155 }
156 W.dfs(1,0);
157 W.solve2();
158 For(i,1,Q) printf("%lld\n",ans[i]);
159 return 0;
160 }
怎么考拉格朗日插值模板题啊。
1 //Achen
2 #include<algorithm>
3 #include<iostream>
4 #include<cstring>
5 #include<cstdlib>
6 #include<vector>
7 #include<cstdio>
8 #include<queue>
9 #include<cmath>
10 #include<set>
11 #include<map>
12 #define For(i,a,b) for(int i=(a);i<=(b);i++)
13 #define Rep(i,a,b) for(int i=(a);i>=(b);i--)
14 const int N=57,mod=1e9+7;
15 typedef long long LL;
16 typedef double db;
17 using namespace std;
18 int T,m;
19 LL n,a[N];
20
21 template<typename T> void read(T &x) {
22 char ch=getchar(); x=0; T f=1;
23 while(ch!='-'&&(ch<'0'||ch>'9')) ch=getchar();
24 if(ch=='-') f=-1,ch=getchar();
25 for(;ch>='0'&&ch<='9';ch=getchar()) x=x*10+ch-'0'; x*=f;
26 }
27
28 bool cmp(const int &A,const int &B) {
29 return A>B;
30 }
31
32 LL ksm(LL a,LL b) {
33 LL rs=1,bs=a%mod;
34 while(b) {
35 if(b&1) rs=rs*bs%mod;
36 bs=bs*bs%mod;
37 b>>=1;
38 }
39 return rs;
40 }
41
42 LL y[N],fac[N],inv[N],p[N],q[N];
43 LL lglr(LL n,int k) {
44 For(i,1,k+2) y[i]=(y[i-1]+ksm(i,k))%mod;
45 if(n<=k+2) return y[n];
46 n%=mod;
47 p[0]=q[k+3]=1;
48 For(i,1,k+2) p[i]=p[i-1]*(n-i+mod)%mod;
49 Rep(i,k+2,1) q[i]=q[i+1]*(n-i+mod)%mod;
50 LL dn=fac[k+1];
51 if((k+1)&1) dn=(mod-dn)%mod;
52 dn=ksm(dn,mod-2);
53 LL rs=0;
54 For(i,1,k+2) {
55 rs=(rs+p[i-1]*q[i+1]%mod*dn%mod*y[i]%mod)%mod;
56 dn=(mod-dn*inv[i]%mod*(k+2-i)%mod)%mod;
57 }
58 return rs;
59 }
60
61 LL ans;
62 void solve(LL n,int m,int k) {
63 for(;;) {
64 ans=(ans+lglr(n,k))%mod;
65 if(!m) break;
66 For(i,1,m) ans=(ans-ksm(a[i],k)+mod)%mod;
67 For(i,1,m-1) a[i]-=a[m];
68 n-=a[m--];
69 }
70 }
71
72 //#define DEBUG
73 int main() {
74 #ifdef DEBUG
75 freopen("1.in","r",stdin);
76 //freopen(".out","w",stdout);
77 #endif
78 read(T);
79 fac[0]=inv[0]=inv[1]=1;
80 For(i,1,55) fac[i]=fac[i-1]*i%mod;
81 For(i,2,55) inv[i]=(mod-mod/i*inv[mod%i]%mod)%mod;
82 while(T--) {
83 read(n); read(m);
84 For(i,1,m) read(a[i]);
85 sort(a+1,a+m+1,cmp);
86 ans=0; solve(n,m,m+1);
87 printf("%lld\n",ans);
88 }
89 return 0;
90 }