T1 最长不下降子序列


数据范围$1e18$很不妙,但模数$d$只有$150$,考虑从这里突破。

计算的式子是个二次函数,结果只与上一个值有关,而模$d$情况下值最多只有$150$个,就证明序列会出现循环。

发现每个循环节的贡献之可能是$1$或$2$(考场没考虑到贡献$2$的情况直接爆$0$),并且贡献为$2$的情况($1$个相等,$1$个大于)最多只有循环节长度$len$个。

那么就可以把贡献为$1$的循环节拎出来不计算,树装数组计算剩余的序列,最后加和即可。

$code:$

 1 #include<bits/stdc++.h>
2 #define int long long
3 using namespace std;
4 int t,n,a,b,c,d,cc[200],tmp,ans,len,pre[200],st;
5 inline int lowbit(int x){ return x&(-x); }
6 inline int read(){
7 int x=0,f=1; char ch=getchar();
8 while(ch<'0'||ch>'9'){ if(ch=='-') f=-1; ch=getchar(); }
9 while(ch>='0'&&ch<='9'){ x=(x<<1)+(x<<3)+(ch^48); ch=getchar(); }
10 return x*f;
11 }
12 inline void write(int x){
13 char ch[20]; int len=0;
14 if(x<0) x=~x+1, putchar('-');
15 do{
16 ch[len++]=x%10+(1<<5)+(1<<4);
17 x/=10;
18 }while(x);
19 for(int i=len-1;i>=0;--i) putchar(ch[i]);
20 }
21 inline void insert(int x,int pos){
22 while(pos<=150){
23 cc[pos]=max(cc[pos],x);
24 pos+=lowbit(pos);
25 }
26 }
27 inline int query(int pos){
28 int res=0;
29 while(pos){
30 res=max(res,cc[pos]);
31 pos-=lowbit(pos);
32 }
33 return res;
34 }
35 signed main(){
36 n=read(); t=read(); a=read(); b=read(); c=read(); d=read();
37 if(n>1000000){
38 tmp=t; pre[t]=1; tmp%=d;
39 for(int i=2;i<=n;i++){
40 tmp=(tmp*tmp*a%d+tmp*b%d+c)%d;
41 if(pre[tmp]){ len=i-pre[tmp]; st=pre[tmp]-1; break; }
42 pre[tmp]=i;
43 }
44 ans=(n-st)/len-150;
45 n=st+len*150+(n-st)%len;
46 }
47 tmp=t; insert(1,tmp+1); tmp%=d;
48 for(int i=2;i<=n;i++){
49 tmp=(tmp*tmp*a%d+tmp*b%d+c)%d;
50 insert(query(tmp+1)+1,tmp+1);
51 }
52 ans+=query(150);
53 write(ans); putchar('\n');
54 return 0;
55 }

T1

T2 完全背包问题


无思路,考场狗了个记搜。

正解分类讨论。当最小的$v$大于等于$l$时最多选$c$个,最大体积为$c*v_{max}$可以直接$DP$。

定义$f_{i,j,k}$为选到第$i$个,最多选$j$个,体积为$k$的方案是否合法。有:

$f_{k,i,j}=f_{k-1,i,j}$ $or$ $f_{k,i-1,j-v_k}$

当最小的$v$(定义为$v_0$)小于$l$时,如果存在体积为$W$的方案,那么一定存在体积为$W+v_0$的方案。直接那么只考虑体积在模$v_0$意义下的合法方案中最小的体积,询问时进行比较即可。

考虑$DP$,意义同上。有:

$f_{k,i,j}=\begin{cases}
min\left ( f_{k-1,i,j},f_{k,i-1,(j-v_k)mod(v_0)}+v_k \right ), &v_k\geq l\\min\left ( f_{k-1,i,j},f_{k,i,(j-v_k)mod(v_0)}+v_k \right ),&v_k<l
\end{cases}$

注意到$DP$状态转移是个环,就用最短路转移。建出一个点数为$v_0+1$的有向图,原点$S$向每个节点$j$连边,边权为$f_{k-1,i,j}$;每个节点$j$向节点$(j+v_k)mod(v_0)$连边,边权为$v_k$。原点与节点$j$的距离即为$f_{k,i,j}$。

注意这样跑最短路算出的$f_{k,i,j}$是正好选了$i$个体积大于等于$l$的物品的最小方案体积,最后要进行覆盖,使它符合定义。

$code:$

 1 #include<bits/stdc++.h>
2 #define int long long
3 using namespace std;
4 int n,m,v[55],l,c,w,f[55][31][10005];
5 int head[20005],to[400005],nex[400005],ew[400005],num;
6 bitset<300005>fl[31][31];
7 inline int read(){
8 int x=0,f=1; char ch=getchar();
9 while(ch<'0'||ch>'9'){ if(ch=='-') f=-1; ch=getchar(); }
10 while(ch>='0'&&ch<='9'){ x=(x<<1)+(x<<3)+(ch^48); ch=getchar(); }
11 return x*f;
12 }
13 inline void write(int x){
14 char ch[20]; int len=0;
15 if(x<0) x=~x+1, putchar('-');
16 do{
17 ch[len++]=x%10+(1<<5)+(1<<4);
18 x/=10;
19 }while(x);
20 for(int i=len-1;i>=0;--i) putchar(ch[i]);
21 }
22 void spfa(int k,int i){
23 bool vis[10005]={0};
24 queue<int>q;
25 q.push(v[1]); vis[v[1]]=1; f[k][i][v[1]]=0;
26 while(!q.empty()){
27 int x=q.front();
28 for(int j=head[x];j;j=nex[j]){
29 int vv=to[j];
30 if(f[k][i][vv]<=f[k][i][x]+ew[j]) continue;
31 f[k][i][vv]=f[k][i][x]+ew[j];
32 if(vis[vv]) continue;
33 vis[vv]=1; q.push(vv);
34 }
35 vis[x]=0; q.pop();
36 }
37 }
38 inline void add(int a,int b,int d){
39 to[++num]=b; nex[num]=head[a]; head[a]=num; ew[num]=d;
40 }
41 void s_l_e(){
42 fl[0][0][0]=1;
43 for(int i=1;i<=n;i++) for(int j=0;j<=c;j++)
44 for(int k=1;k<c*v[n];k++)
45 if(k>=v[i]) fl[i][j][k]=fl[i-1][j][k]|fl[i][j-1][k-v[i]];
46 else fl[i][j][k]=f[i-1][j][k];
47 while(m--){
48 w=read();
49 bool flag=0;
50 if(w>c*v[n]){ puts("No"); continue; }
51 puts(fl[n][c][w]?"Yes":"No");
52 }
53 }
54 void _o_v_(){
55 for(int i=0;i<=n;i++) for(int j=0;j<=c;j++)
56 for(int k=0;k<=v[1];k++) f[i][j][k]=3e18;
57 f[0][0][0]=0;
58 for(int k=1;k<=n;k++)
59 if(v[k]>=l){
60 for(int i=0;i<=c;i++)
61 for(int j=0;j<v[1];j++)
62 if(!i) f[k][i][j]=f[k-1][i][j];
63 else f[k][i][j]=min(f[k-1][i][j],f[k][i-1][(j-v[k]%v[1]+v[1])%v[1]]+v[k]);
64 }
65 else
66 for(int i=0;i<=c;i++){
67 memset(head,0,sizeof(head)); num=0;
68 for(int j=0;j<v[1];j++)
69 add(j,(j+v[k])%v[1],v[k]), add(v[1],j,f[k-1][i][j]);
70 spfa(k,i);
71 }
72 for(int i=1;i<=c;i++)
73 for(int j=0;j<v[1];j++)
74 f[n][i][j]=min(f[n][i][j],f[n][i-1][j]);
75 while(m--){
76 w=read();
77 puts(w>=f[n][c][w%v[1]]?"Yes":"No");
78 }
79 }
80 signed main(){
81 // freopen("bag0.in","r",stdin);
82 // freopen("out","w",stdout);
83 n=read(); m=read();
84 for(int i=1;i<=n;i++) v[i]=read();
85 sort(v+1,v+n+1);
86 l=read(); c=read();
87 if(v[1]>=l) s_l_e();
88 else _o_v_();
89 return 0;
90 }

T2

T3 最近公共祖先


树剖,每次染色时跳父亲,修改路径上每个点除了链上子树其他子树中所有点的最大值,遇到已修改过的点就停,避免重复修改,可以保证每个点只被修改一次。

查询时单点查询即可。

$code:$

  1 #include<bits/stdc++.h>
2 #define ld rt<<1
3 #define rd (rt<<1)|1
4 using namespace std;
5 const int NN=1e5+5;
6 int n,m,num,to[NN<<1],nex[NN<<1],head[NN],w[NN],op;
7 int dep[NN],siz[NN],son[NN],top[NN],fa[NN],dfn[NN],id[NN],cnt;
8 char opt[10];
9 bool vis[NN];
10 inline int read(){
11 int x=0,f=1; char ch=getchar();
12 while(ch<'0'||ch>'9'){ if(ch=='-') f=-1; ch=getchar(); }
13 while(ch>='0'&&ch<='9'){ x=(x<<1)+(x<<3)+(ch^48); ch=getchar(); }
14 return x*f;
15 }
16 inline void write(int x){
17 char ch[20]; int len=0;
18 if(x<0) x=~x+1, putchar('-');
19 do{
20 ch[len++]=x%10+(1<<5)+(1<<4);
21 x/=10;
22 }while(x);
23 for(int i=len-1;i>=0;--i) putchar(ch[i]);
24 }
25 inline void add(int a,int b){
26 to[++num]=b; nex[num]=head[a]; head[a]=num;
27 to[++num]=a; nex[num]=head[b]; head[b]=num;
28 }
29 void dfs1(int f,int s){
30 fa[s]=f; dep[s]=dep[f]+1; siz[s]=1;
31 for(int i=head[s];i;i=nex[i]){
32 int v=to[i];
33 if(v==f) continue;
34 dfs1(s,v);
35 siz[s]+=siz[v];
36 if(siz[v]>siz[son[s]]) son[s]=v;
37 }
38 }
39 void dfs2(int t,int s){
40 top[s]=t; dfn[s]=++cnt; id[cnt]=s;
41 if(!son[s]) return;
42 dfs2(t,son[s]);
43 for(int i=head[s];i;i=nex[i]){
44 int v=to[i];
45 if(v!=fa[s]&&v!=son[s]) dfs2(v,v);
46 }
47 }
48 struct segment_tree{
49 int l[NN<<2],r[NN<<2],mx[NN<<2],laz[NN<<2];
50 void pushup(int rt){
51 if(l[rt]==r[rt]) return;
52 mx[rt]=max(mx[ld],mx[rd]);
53 }
54 void pushdown(int rt){
55 if(!laz[rt]||l[rt]==r[rt]) return;
56 mx[ld]=max(laz[rt],mx[ld]); mx[rd]=max(laz[rt],mx[rd]);
57 laz[ld]=max(laz[ld],laz[rt]); laz[rd]=max(laz[rd],laz[rt]);
58 laz[rt]=0;
59 }
60 void build(int rt,int opl,int opr){
61 l[rt]=opl; r[rt]=opr; mx[rt]=-1;
62 if(opl==opr) return;
63 int mid=opl+opr>>1;
64 build(ld,opl,mid);
65 build(rd,mid+1,opr);
66 }
67 void update(int rt,int opl,int opr,int val){
68 if(l[rt]>=opl&&r[rt]<=opr){
69 mx[rt]=max(mx[rt],val);
70 laz[rt]=max(laz[rt],val);
71 return;
72 }
73 pushdown(rt);
74 int mid=l[rt]+r[rt]>>1;
75 if(opl<=mid) update(ld,opl,opr,val);
76 if(opr>mid) update(rd,opl,opr,val);
77 pushup(rt);
78 }
79 int query(int rt,int pos){
80 if(l[rt]==r[rt]) return mx[rt];
81 pushdown(rt);
82 int mid=l[rt]+r[rt]>>1,ans=-1;
83 if(pos<=mid) return query(ld,pos);
84 else return query(rd,pos);
85 }
86 }s;
87 void UPD(int x){
88 s.update(1,dfn[x],dfn[x]+siz[x]-1,w[x]);
89 while(fa[x]!=0&&!vis[x]){
90 vis[x]=1;
91 s.update(1,dfn[fa[x]],dfn[x]-1,w[fa[x]]);
92 s.update(1,dfn[x]+siz[x],dfn[fa[x]]+siz[fa[x]]-1,w[fa[x]]);
93 x=fa[x];
94 }
95 }
96 signed main(){
97 n=read(); m=read();
98 for(int i=1;i<=n;i++) w[i]=read();
99 for(int i=1;i<n;i++) add(read(),read());
100 dfs1(0,1); dfs2(1,1); s.build(1,1,n);
101 while(m--){
102 scanf("%s",opt); op=read();
103 if(opt[0]=='M') UPD(op);
104 else write(s.query(1,dfn[op])), putchar('\n');
105 }
106 return 0;
107 }

T3

最新文章

  1. css使一行文字竖向排列
  2. [deviceone开发]-QQ分享、微信分享和新浪微博分享
  3. Junit单步调试
  4. jQuery 中屏蔽浏览器的F5刷新功能
  5. [转]caffe+Ubuntu14.0.4 64bit 环境配置说明(无CUDA,caffe在CPU下运行) --for --Amd
  6. Extjs ajax form 提交
  7. BF533的SPORT接口
  8. C++ 设计模式 开放封闭原则 简单示例
  9. Scala环境(集成idea)
  10. Docker(十九)-Docker监控容器资源的占用情况
  11. JSP错误
  12. 2017-2018-1 20155234 实验三 实时系统及mypwd实现
  13. vue 实战报错解决方案
  14. ANSI、GBK、GB2312、UTF-8、GB18030和 UNICODE
  15. SVN常见问题及解决方法(转载)
  16. while an existing transition or presentation is occurring; the navigation stack will not be updated
  17. Traefik的TLS配置
  18. readfile()
  19. 实践作业3:白盒测试---细化明确任务DAY5
  20. 国外物联网平台(8):Telit

热门文章

  1. JS003. 事件监听和监听滚动条的三种参数( addEventListener( ) )
  2. vs2015使用tcmalloc(windows)
  3. Spring5(七)——AOP注解
  4. 【第十篇】- Git 远程仓库(Github)之Spring Cloud直播商城 b2b2c电子商务技术总结
  5. Linux上合理设置网卡的MTU值
  6. 【OI】WERTYU UVa 10082
  7. nginx proxy_next_upstream 与openresty balancer.set_more_tries的使用
  8. 【PHP数据结构】图的应用:最短路径
  9. [PhpStorm]解决Cannot find declaration to go to
  10. Shell系列(38)- 数组操作→取值、遍历、替换、删除