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

2021.8.3考试总结[NOIP模拟29]的更多相关文章

  1. 2021.9.17考试总结[NOIP模拟55]

    有的考试表面上自称NOIP模拟,背地里却是绍兴一中NOI模拟 吓得我直接文件打错 T1 Skip 设状态$f_i$为最后一次选$i$在$i$时的最优解.有$f_i=max_{j<i}[f_j+a ...

  2. 2021.9.13考试总结[NOIP模拟52]

    T1 路径 考虑每一位的贡献,第$i$位每$2^i$个数会变一次,那么答案为$\sum_{i=1}^{log_2n} \frac{n}{2^i}$. $code:$ 1 #include<bit ...

  3. 2021.8.11考试总结[NOIP模拟36]

    T1 Dove玩扑克 考场并查集加树状数组加桶期望$65pts$实际$80pts$,考后多开个数组记哪些数出现过,只扫出现过的数就切了.用$set$维护可以把被删没的数去掉,更快. $code:$ 1 ...

  4. 2021.7.15考试总结[NOIP模拟16]

    ZJ模拟D2就是NB.. T1 Star Way To Heaven 谁能想到这竟是个最小生成树呢?(T1挂分100的高人JYF就在我身边 把上边界和下边界看成一个点和星星跑最小生成树,从上边界开始跑 ...

  5. 2021.10.7考试总结[NOIP模拟71]

    信心赛,但炸了.T3SB错直接炸飞,T4可以硬算的组合数非要分段打表求阶乘..T2也因为一个细节浪费了大量时间.. 会做难题很好,但首先还是要先把能拿的分都拿到. T1 签到题 结论:总可以做到对每个 ...

  6. 2021.9.20考试总结[NOIP模拟57]

    (换个编辑器代码就SB地不自动折叠了.. T1 2A 考察快读的写法. $code:$ T1 #include<bits/stdc++.h> #define scanf SCANF=sca ...

  7. 2021.9.14考试总结[NOIP模拟53]

    T1 ZYB和售货机 容易发现把每个物品都买成$1$是没有影响的. 然后考虑最后一个物品的方案,如果从$f_i$向$i$连边,发现每个点有一个出度多个入度,可以先默认每个物品都能买且最大获利,这样可以 ...

  8. 2021.9.12考试总结[NOIP模拟51]

    T1 茅山道术 仔细观察发现对于每个点只考虑它前面第一个与它颜色相同的点即可. 又仔细观察发现对一段区间染色后以这个区间内点为端点的区间不能染色. 于是对区间右端点而言,区间染色的贡献为遍历到区间左端 ...

  9. 2021.9.9考试总结[NOIP模拟50]

    T1 第零题 神秘结论:从一个点满体力到另一个点的复活次数与倒过来相同. 于是预处理出每个点向上走第$2^i$个死亡点的位置,具体实现可以倍增或二分. 每次询问先从两个点同时向上倍增,都转到离$LCA ...

随机推荐

  1. CSS导航菜单(二级菜单)

    index.html <div class="nav"> <ul> <li> <a href="#">Java& ...

  2. AQS快速入门

    一.模板方法模式 父子类多态,父类中用一个方法调用执行所有所需要的方法: 父类: 子类: 主线程执行时候调用父类的模板方法: 二.AQS思想 sync都是独占锁,lock显示锁也是,只有读写锁是共享锁 ...

  3. Java入门准备:Java开发环境的安装与卸载

    Java的三大版本 JavaSE:标准版 JavaME:嵌入式开发 JavaEE:企业级开发 JDK(Java Development Kit):Java开发者工具包 JRE(Java Runtime ...

  4. CodeForce-797C Minimal string(贪心模拟)

    Minimal string CodeForces - 797C Petya 收到一个长度不超过 105 的字符串 s.他拿了两个额外的空字符串 t 和 u 并决定玩一个游戏.这个游戏有两种合法操作: ...

  5. .NET 中的HTTP 3支持

    dotnet团队官方博客发布了一篇HTTP3的文章:HTTP/3 support in .NET 6.文章介绍了.NET 6 将预览支持HTTP3,.NET 7正式支持HTTP3,原因主要是HTTP/ ...

  6. webpack4 使用babel处理ES6语法的一些简单配置

    一,安装包 npm install --save-dev babel-loader @babel/corenpm install @babel/preset-env --save-devnpm ins ...

  7. mysql将数据导入到另外一张操作

    insert into ydcq_member_class (ClassId,signcount,UserId) select 64,2,`员工编号` from `学员名单`

  8. requests接口自动化-列表与字典参数化

    def server_ip(): # 配置文件,通过修改配置,在不同环境进行测试 # dev_ip='https://www.baidu.com/' # sit_ip='https://cn.bing ...

  9. python学习2-博客-蓝图

    #!/usr/bin/env python # -*- coding: UTF-8 -*- from flask import Blueprint,Flask #这里创建了一个名称为 'admin' ...

  10. 关于Postman你必须学会的技能

    关于Postman 工欲善其事,必先利其器,在了解了接口测试之后,就要选择一款适用的工具.之所以选择postman是因为它简单.容易上手.能覆盖大多数HTTP接口测试场景,性价比极高. Postman ...