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;
}
View Code

 

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 }
View Code

 

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 }
View Code

 

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;
}
View Code

 

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 }
View Code

 

d2t3[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=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 }
View Code

 

posted @ 2018-05-22 11:56  啊宸  阅读(380)  评论(0编辑  收藏  举报