2021 icpc 南京游记

打铜了

爬了


补题:

$I$

一道终极歪榜题

路线事实上一共有$2H$种,可以映射到$[-H,H)$上,$\ge 0 $的部分表示$x=0$时向上

用$map$简单维护一下即可

 1 #include<bits/stdc++.h>
 2 #define inf 2139062143
 3 #define ll long long
 4 #define db double
 5 #define ld long double
 6 #define ull unsigned long long
 7 #define MAXN 100100
 8 #define MOD 998244353
 9 #define Fill(a,x) memset(a,x,sizeof(a))
10 #define rep(i,s,t) for(int i=(s),i##end=(t);i<=i##end;++i)
11 #define dwn(i,s,t) for(int i=(s),i##end=(t);i>=i##end;--i)
12 #define ren for(int i=fst[x];i;i=nxt[i])
13 #define pii pair<int,int>
14 #define vi vector<int>
15 #define fi first
16 #define se second
17 #define pb push_back
18 using namespace std;
19 inline int read()
20 {
21     int x=0,f=1;char ch=getchar();
22     while(!isdigit(ch)) {if(ch=='-') f=-1;ch=getchar();}
23     while(isdigit(ch)) {x=x*10+ch-'0';ch=getchar();}
24     return x*f;
25 }
26 namespace CALC
27 {
28     inline int pls(int a,int b){return a+b>=MOD?a+b-MOD:(a+b<0?a+b+MOD:a+b);}
29     inline int mns(int a,int b){return a-b<0?a-b+MOD:(a-b>=MOD?a-b-MOD:a-b);}
30     inline int mul(int a,int b){return (1LL*a*b)%MOD;}
31     inline void inc(int &a,int b){a=pls(a,b);}
32     inline void dec(int &a,int b){a=mns(a,b);}
33     inline void tms(int &a,int b){a=mul(a,b);}
34     inline int qp(int x,int t,int res=1)
35         {for(;t;t>>=1,x=mul(x,x)) if(t&1) res=mul(res,x);return res;}
36     inline int Inv(int x){return qp(x,MOD-2);}
37 }
38 using namespace CALC;
39 int H,n,m,ans;
40 pii g[MAXN<<1];
41 map<int,int> res;
42 int main()
43 {
44     rep(T,1,read())
45     {
46         ans=0;res.clear();res[0]=0;
47         H=read();n=read();int x,y,ya,yb,tmp;
48         rep(i,1,n) g[i].fi=read(),g[i].se=read();
49         m=read();rep(i,1,m) g[i+n].fi=read(),g[i+n].se=0-read();
50         sort(g+1,g+n+m+1);
51         rep(i,1,n+m)
52         {
53             x=g[i].fi,y=abs(g[i].se);
54             x%=2*H;if(x>=H) y=H-y,x-=H;
55             ya=y-x,yb=y+x<=H?-y-x:2*H-y-x;
56             if(g[i].se>0&&(res.count(ya)||res.count(yb)))
57                 tmp=max(res[ya],res[yb]),res[ya]=res[yb]=tmp;
58             else if(g[i].se<0)
59             {
60                 if(res.count(ya)) res[ya]++,ans=max(ans,res[ya]);
61                 if(res.count(yb)) res[yb]++,ans=max(ans,res[yb]);
62             }
63         }
64         printf("%d\n",ans);
65     }
66 }
View Code

 

$J$

搜索题

每次枚举两个数之差$d$的质因数$p$,则这一次的最优操作一定是通过加减得到上/下取整

 1 #include<bits/stdc++.h>
 2 #define inf 2139062143
 3 #define ll long long
 4 #define db double
 5 #define ld long double
 6 #define ull unsigned long long
 7 #define MAXN 100100
 8 #define MOD 998244353
 9 #define Fill(a,x) memset(a,x,sizeof(a))
10 #define rep(i,s,t) for(int i=(s),i##end=(t);i<=i##end;++i)
11 #define dwn(i,s,t) for(int i=(s),i##end=(t);i>=i##end;--i)
12 #define ren for(int i=fst[x];i;i=nxt[i])
13 #define pii pair<int,int>
14 #define vi vector<int>
15 #define fi first
16 #define se second
17 #define pb push_back
18 using namespace std;
19 inline int read()
20 {
21     int x=0,f=1;char ch=getchar();
22     while(!isdigit(ch)) {if(ch=='-') f=-1;ch=getchar();}
23     while(isdigit(ch)) {x=x*10+ch-'0';ch=getchar();}
24     return x*f;
25 }
26 namespace CALC
27 {
28     inline int pls(int a,int b){return a+b>=MOD?a+b-MOD:(a+b<0?a+b+MOD:a+b);}
29     inline int mns(int a,int b){return a-b<0?a-b+MOD:(a-b>=MOD?a-b-MOD:a-b);}
30     inline int mul(int a,int b){return (1LL*a*b)%MOD;}
31     inline void inc(int &a,int b){a=pls(a,b);}
32     inline void dec(int &a,int b){a=mns(a,b);}
33     inline void tms(int &a,int b){a=mul(a,b);}
34     inline int qp(int x,int t,int res=1)
35         {for(;t;t>>=1,x=mul(x,x)) if(t&1) res=mul(res,x);return res;}
36     inline int Inv(int x){return qp(x,MOD-2);}
37 }
38 using namespace CALC;
39 int p[MAXN],ntp[MAXN],tot;
40 map<pii,int> m;
41 void init(int n)
42 {
43     rep(i,2,n)
44     {
45         if(!ntp[i]) p[++tot]=i;
46         rep(j,1,tot) if(p[j]*i>n) break;
47             else{ntp[i*p[j]]=1;if(i%p[j]==0) break;}
48     }
49 }
50 int dfs(int x,int d)
51 {
52     //cout<<x<<" "<<d<<endl;
53     if(x==1) return 0;
54     if(d==1) return x-1;
55     if(m.count({x,d})) return m[{x,d}];
56     int res=x-1,pi,now=d;
57     rep(i,1,tot) if(p[i]*p[i]>now) break;
58         else if(now%p[i]==0)
59         {
60             pi=p[i];
61             if(x%pi==0) res=min(res,dfs(x/pi,d/pi)+1);
62             else
63             {
64                 if(x>=pi) res=min(res,dfs(x/pi,d/pi)+1+x%pi);
65                 res=min(res,dfs((x+pi-1)/pi,d/pi)+1+pi-x%pi);
66             }
67             while(now%p[i]==0) now/=p[i];
68         }
69     if(now>100000||(now>1&&!ntp[now]))
70     {
71         pi=now;
72         if(x%pi==0) res=min(res,dfs(x/pi,d/pi)+1);
73         else
74         {
75             if(x>=pi) res=min(res,dfs(x/pi,d/pi)+1+x%pi);
76             res=min(res,dfs((x+pi-1)/pi,d/pi)+1+pi-x%pi);
77         }
78     }
79     return m[{x,d}]=res;
80 }
81 int main()
82 {
83     init(1e5);
84     rep(T,1,read())
85     {
86         int a=read(),b=read();
87         if(a>b) swap(a,b);
88         printf("%d\n",dfs(a,b-a));
89     }
90 }
View Code

 

$E$

照着官方题解写的:

  1 #include<bits/stdc++.h> 
  2 #define ll long long
  3 #define inf 2139062143
  4 #define MAXN 100100
  5 #define MOD 1000000007
  6 #define pii pair<int,int>
  7 #define rep(i,s,t) for(int i=(s),i##end=(t);i<=i##end;++i)
  8 #define dwn(i,s,t) for(int i=(s),i##end=(t);i>=i##end;--i)
  9 #define pb push_back
 10 using namespace std;
 11 inline int read()
 12 {
 13     int x=0,f=1;char ch=getchar();
 14     while(!isdigit(ch)) {if(ch=='-') f=-1;ch=getchar();}
 15     while(isdigit(ch)) x=x*10+ch-'0',ch=getchar();
 16     return x*f;
 17 }
 18 inline int pls(int a,int b){return a+b>=MOD?a+b-MOD:a+b;}
 19 inline int mns(int a,int b){return a-b<0?a-b+MOD:a-b;}
 20 inline int mul(int a,int b){return 1LL*a*b%MOD;}
 21 inline int sqr(int x){return mul(x,x);}
 22 inline void inc(int &a,int b){a=pls(a,b);}
 23 inline void dec(int &a,int b){a=mns(a,b);}
 24 inline void tms(int &a,int b){a=mul(a,b);}
 25 struct mat
 26 {
 27     int a[6];
 28     void mem(){memset(a,0,sizeof(a));}
 29     void getw(int w){a[0]=w;a[1]=a[2]=sqr(w),a[3]=a[4]=mul(2,w),a[5]=1;}
 30     mat operator * (const mat &x)
 31     {
 32         mat res;
 33         res.a[0]=pls(a[0],x.a[0]);
 34         res.a[1]=pls(pls(x.a[1],a[1]),mul(a[0],x.a[3]));
 35         res.a[2]=pls(x.a[2],a[2]);
 36         inc(res.a[2],pls(mul(a[0],x.a[4]),mul(a[1],x.a[5])));
 37         res.a[3]=pls(a[3],x.a[3]);
 38         res.a[4]=pls(pls(x.a[4],a[4]),mul(a[3],x.a[5]));
 39         res.a[5]=pls(a[5],x.a[5]);
 40         return res;
 41     }
 42     bool operator == (const mat &x)
 43     {
 44         rep(i,0,5) if(a[i]!=x.a[i]) return 0;
 45         return 1;
 46     }
 47 }tag[MAXN<<2],zr;
 48 struct vec
 49 {
 50     int a[4];
 51     vec operator + (const vec &x)
 52     {
 53         vec res;rep(i,0,3) res.a[i]=pls(a[i],x.a[i]);
 54         return res;
 55     }
 56     vec operator * (const mat &x)
 57     {
 58         vec res;
 59         res.a[0]=a[0];
 60         res.a[1]=pls(mul(x.a[0],a[0]),a[1]);
 61         res.a[2]=pls(pls(mul(x.a[1],a[0]),mul(x.a[3],a[1])),a[2]);
 62         res.a[3]=pls(pls(mul(x.a[2],a[0]),mul(x.a[4],a[1])),pls(mul(x.a[5],a[2]),a[3]));
 63         return res;
 64     }
 65 }tr[MAXN<<2];
 66 int n,m,Q,h[MAXN],res[MAXN];
 67 struct Ask{int x,l,r,w,id;}q[MAXN];
 68 struct Data{int l,r,w;}g[MAXN];
 69 bool operator < (const Ask &a,const Ask &b){return a.x<b.x;}
 70 inline void upd(int k){tr[k]=tr[k<<1]+tr[k<<1|1];}
 71 void build(int k,int l,int r)
 72 {
 73     if(l==r) {tr[k]={1,h[l],sqr(h[l]),sqr(h[l])};return ;}
 74     int mid=l+r>>1;build(k<<1,l,mid);build(k<<1|1,mid+1,r);
 75     upd(k);
 76 }
 77 inline void Mdf(int k,mat w){tr[k]=tr[k]*w,tag[k]=tag[k]*w;}
 78 void pshd(int k)
 79 {
 80     if(tag[k]==zr) return ;
 81     Mdf(k<<1,tag[k]);Mdf(k<<1|1,tag[k]);tag[k].mem();
 82 }
 83 int query(int k,int l,int r,int a,int b)
 84 {
 85     if(a<=l&&r<=b) return tr[k].a[3];
 86     int mid=l+r>>1,res=0;pshd(k);
 87     if(a<=mid) inc(res,query(k<<1,l,mid,a,b));
 88     if(b>mid) inc(res,query(k<<1|1,mid+1,r,a,b));
 89     return res;
 90 }
 91 void mdf(int k,int l,int r,int a,int b,mat w)
 92 {
 93     if(a<=l&&r<=b){Mdf(k,w);return ;}
 94     int mid=l+r>>1;pshd(k);
 95     if(a<=mid) mdf(k<<1,l,mid,a,b,w);
 96     if(b>mid) mdf(k<<1|1,mid+1,r,a,b,w);
 97     upd(k);
 98 }
 99 int main()
100 {
101     n=read(),m=read(),Q=read();rep(i,1,n) h[i]=pls(read(),MOD);
102     build(1,1,n);int a,b,c,d;
103     zr.mem();mat tmp;
104     rep(i,1,m) g[i].l=read(),g[i].r=read(),g[i].w=pls(read(),MOD);
105     rep(i,0,Q-1) a=read(),b=read(),c=read(),d=read(),q[i*2+1]={c-1,a,b,-1,i+1},q[i*2+2]={d,a,b,1,i+1};
106     Q<<=1;sort(q+1,q+Q+1);int pos=1;
107     while(q[pos].x==-1) pos++;
108     rep(i,0,m)
109     {
110         if(i)
111         {
112             tmp.getw(g[i].w);
113             mdf(1,1,n,g[i].l,g[i].r,tmp);
114             tmp.getw(0);
115             if(g[i].l>1) mdf(1,1,n,1,g[i].l-1,tmp);
116             if(g[i].r<n) mdf(1,1,n,g[i].r+1,n,tmp);
117         }
118         while(pos<=Q&&q[pos].x<=i)
119         {
120             if(q[pos].w==1) inc(res[q[pos].id],query(1,1,n,q[pos].l,q[pos].r));
121             else dec(res[q[pos].id],query(1,1,n,q[pos].l,q[pos].r));
122             pos++;
123         }
124     }
125     rep(i,1,Q>>1) printf("%d\n",res[i]);
126 }
View Code

 

$G$

使用题解中所述的dp,实际中可以通过一个操作把题解中的mask状态省去

即每一个点再向外额外连一个点,这样当$dp(u,v,t)$中$u,v$有额外节点时,即代表了这一段不可扩展

因此在新的树中,$dp(u,v,t)$表示$u~v$路径上不算最外面两条边的答案

 1 #include<bits/stdc++.h> 
 2 #define ll long long
 3 #define MAXN 100100
 4 #define pii pair<int,int>
 5 #define rep(i,s,t) for(int i=(s),i##end=(t);i<=i##end;++i)
 6 #define dwn(i,s,t) for(int i=(s),i##end=(t);i>=i##end;--i)
 7 #define ren for(int i=fst[x];i;i=nxt[i])
 8 #define pb push_back
 9 using namespace std;
10 inline int read()
11 {
12     int x=0,f=1;char ch=getchar();
13     while(!isdigit(ch)) {if(ch=='-') f=-1;ch=getchar();}
14     while(isdigit(ch)) x=x*10+ch-'0',ch=getchar();
15     return x*f;
16 }
17 const ll inf=1e18;
18 int n,val[310];
19 vector<int> G[310];
20 int fa[310][310],sz[310][310];
21 ll f[155][310][310];
22 void dfs(int x,int pa,const int& anc)
23 {
24     fa[anc][x]=pa,sz[anc][x]=(x<=n);
25     for(auto v:G[x]) if(v^pa)
26         dfs(v,x,anc),sz[anc][x]+=sz[anc][v];
27 }
28 void solve()
29 {
30     n=read()+1;int a,b;
31     rep(i,1,n-1) val[i]=read();
32     rep(i,1,n-1) a=read(),b=read(),G[a].pb(b),G[b].pb(a);
33     rep(i,1,n)  G[i].pb(i+n),G[i+n].pb(i);
34     rep(i,1,n<<1) dfs(i,0,i);
35     rep(t,0,n-1) rep(i,1,n<<1) rep(j,1,n<<1) f[t][i][j]=-inf;
36     rep(x,1,n) rep(i,0,G[x].size()-1) rep(j,i+1,G[x].size()-1)
37         f[0][G[x][i]][G[x][j]]=f[0][G[x][j]][G[x][i]]=0;
38     rep(t,0,n-2) rep(i,1,n<<1) rep(j,i+1,n<<1) if(f[t][i][j]>=0)
39     {
40         //cout<<t<<" "<<i<<" "<<j<<" "<<f[t][i][j]<<endl;
41         if(n-1-sz[i][j]-sz[j][i]>=t+1)
42             f[t+1][i][j]=f[t+1][j][i]=max(f[t+1][i][j],f[t][i][j]);
43         for(auto v:G[i]) if(v^fa[j][i])
44             f[t+1][j][v]=f[t+1][v][j]=max(f[t+1][j][v],f[t][i][j]+val[t+1]);
45         for(auto v:G[j]) if(v^fa[i][j])
46             f[t+1][i][v]=f[t+1][v][i]=max(f[t+1][i][v],f[t][i][j]+val[t+1]);
47     }
48     ll ans=0;
49     rep(i,1,n<<1) rep(j,i+1,n<<1) ans=max(ans,f[n-1][i][j]);
50     printf("%lld\n",ans);
51     rep(i,1,n<<1) G[i].clear();
52 }
53 int main()
54 {
55     rep(T,1,read()) solve();
56 }
View Code

 

posted @ 2021-12-07 18:31  jack_yyc  阅读(143)  评论(0编辑  收藏  举报