t3:

题意

给你一棵树,然后每次两种操作:1.给一个节点染色 ; 2. 查询一个节点与任意已染色节点 lca 的权值的最大值

分析

考虑一个节点被染色后的影响:令它的所有祖先节点(包括自身)的所有除去更新节点上来的整棵子树的所有节点更新。

那么考虑dfs序会使某节点的子树节点连成一片,所以不更新某棵子树就可以轻易做到

然后考虑用线段树维护,复杂度就是 n log n

code

 //by Judge
#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int M=2e5+;
#define getchar() (p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<21,stdin),p1==p2)?EOF:*p1++)
char buf[<<],*p1,*p2;
inline int Max(int a,int b){return a>b?a:b;}
inline void cmax(int& a,int b){if(a<b)a=b;}
inline int read(){ int x=,f=; char c=getchar();
for(;!isdigit(c);c=getchar()) if(c=='-') f=-;
for(;isdigit(c);c=getchar()) x=x*+c-''; return x*f;
} inline int cread(){ char c=getchar();
while(!isupper(c)) c=getchar(); return c=='M';
} char sr[<<],z[]; int Z,C=-;
inline void Ot(){fwrite(sr,,C+,stdout),C=-;}
inline void print(int x,char ch='\n'){
if(C><<) Ot();if(x<)sr[++C]='-',x=-x;
for(;z[++Z]=x%+,x/=;);
for(;sr[++C]=z[Z],--Z;);sr[++C]=ch;
} int n,m,pat,cnt,v[M];
int f[M],head[M],dfn[M],siz[M];
struct Edge{ int to,next; }e[M<<];
inline void add(int u,int v){
e[++pat]=(Edge){v,head[u]},head[u]=pat;
e[++pat]=(Edge){u,head[v]},head[v]=pat;
}
#define v e[i].to
void dfs(int u){ dfn[u]=++cnt,siz[u]=;
for(int i=head[u];i;i=e[i].next)
if(v^f[u]) f[v]=u,dfs(v),siz[u]+=siz[v];
}
#undef v
struct segT{ int mx[M<<];
#define ls k<<1
#define rs k<<1|1
#define mid (l+r>>1)
#define lson ls,l,mid
#define rson rs,mid+1,r
inline void clear(){memset(mx,-,sizeof(mx));}
void modify(int k,int l,int r,int L,int R,int v){
if(v<mx[k]||L>r||l>R) return ;
if(L<=l&&r<=R) return mx[k]=v,void();
modify(lson,L,R,v),modify(rson,L,R,v);
}
int query(int k,int l,int r,int x){ if(l==r) return mx[k];
if(x<=mid) return Max(mx[k],query(lson,x));
else return Max(mx[k],query(rson,x));
}
inline void modify(int x,int y,int v){ if(!y) modify(,,n,dfn[x],dfn[x]+siz[x]-,v);
else modify(,,n,dfn[x],dfn[y]-,v),modify(,,n,dfn[y]+siz[y],dfn[x]+siz[x]-,v);
}
inline int query(int x){ return query(,,n,dfn[x]); }
}t;
bool B[M];
inline void modify(int x){
for(int las=;x;las=x,x=f[x]){
t.modify(x,las,v[x]);
if(B[x]) return ; B[x]=;
}
}
int main(){
freopen("lca.in","r",stdin);
freopen("lca.out","w",stdout);
n=read(),m=read();
for(int i=;i<=n;++i) v[i]=read();
for(int i=,a,b;i<n;++i)
a=read(),b=read(),add(a,b);
dfs(),t.clear();
for(int op,x;m;--m){
op=cread(),x=read();
if(op) modify(x);
else print(t.query(x));
} return Ot(),;
}

t1:

题意

给你一个序列 a ,长度为 n ,首项为 t0,后面每一项 $a[i] = (A*a[i-1]*a[i-1]+B*a[i-1]+C)%D$  , A、 B、 C、 D 均给出,求这个序列的最长不下降子序列

分析

一眼看出这玩意儿有循环节。

但是这个序列前面的一部分与最后的一部分要特殊考虑,后面一部分倒还好说,前面一部分根本就与循环节是无关的。

所以我们考虑前后两部分特殊处理,然后中间的部分利用循环节做掉。

做法有两种:

  1. 一个是列出转移式然后矩阵加速解,复杂度  $D^3 \log n$
  2. 一个是考虑贪心构造,观察出每个数字必然至少出现一次的特点(当然是 n 足够大的时候),将中间的每个循环中的数字能利用就利用上,然后对于 n 小一点的直接 n log n 跑一遍暴力解(n^3 也可以随你开心啦) 复杂度 $D^2 \log D$

  

code

$D^3 \log n$

 //by Judge
#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int M=1e6+;
const int N=;
int A,B,C,D,a[M],f[M];
int b[M<<],c[M],pos[M];
ll n,m,st,ed,top,ans=,MX[M];
template<class T>inline void cmax(T& a,T b){if(a<b)a=b;}
inline int get(int x){return (A*x*x+B*x+C)%D;}
inline void solv_pre(){
for(int i=;i<=n;++i) a[i]=get(a[i-]);
for(int i=,k;i<=n;++i){
k=upper_bound(f+,f++top,a[i])-f;
if(k>top) ++top; f[k]=a[i],MX[a[i]]=k;
}
for(int i=;i<=D;++i) cmax(ans,MX[i]);
printf("%lld\n",ans);
}
struct Matrix{ ll a[N][N];
inline void mem(){ memset(a,-,sizeof(a)); }
ll* operator [](const int x){return a[x];}
Matrix operator *(Matrix& b){ static Matrix c;
for(int i=;i<=m;++i) for(int j=;j<=m;++j) c[i][j]=-;
for(int i=;i<=m;++i) for(int k=;k<=m;++k)
for(int j=;j<=m;++j) if(a[i][k]!=-&&b[k][j]!=-)
cmax(c[i][j],a[i][k]+b[k][j]); return c;
}
}I,G;
Matrix qpow(Matrix x,ll p){ Matrix s=I;
for(ll i=p;i;i>>=,x=x*x)
if(i&) s=s*x; return s;
}
int lf[N],rf[N];
int main(){
freopen("lis.in","r",stdin);
freopen("lis.out","w",stdout);
cin>>n>>a[]>>A>>B>>C>>D,pos[a[]]=;
if(n<=1e6) return solv_pre(),;
for(int i=;;pos[a[i]]=i,++i){ a[i]=get(a[i-]);
if(pos[a[i]]){st=i,m=i-pos[a[i]];break;}
} ed=n-(n-st+)%m,b[]=c[]=a[st];
for(int i=;i<=m<<;++i) b[i]=get(b[i-]);
for(int i=;i<=n-ed;++i) c[i]=get(c[i-]);
I.mem(),G.mem(); for(int i=;i<=m;++i) I[i][i]=;
for(int i=;i<st;cmax(lf[a[i]],++f[i]),++i)
for(int j=;j<i;++j) if(a[j]<=a[i]) cmax(f[i],f[j]);
for(int i=;i<=D;++i) cmax(lf[i],lf[i-]);
memset(f,,sizeof(f));
for(int i=n-ed;i>=;cmax(rf[c[i]],++f[i]),--i)
for(int j=n-ed;j>i;--j) if(c[j]>=c[i]) cmax(f[i],f[j]);
for(int i=D-;i>=;--i) cmax(rf[i],rf[i+]);
for(int i=;i<=m;++i){ memset(f,-,sizeof(f)),f[i]=;
for(int j=i+;j<=m<<;++j) if(b[j]>=b[i])
for(int k=i;k<j;++k) if(b[k]<=b[j]) cmax(f[j],f[k]+);
for(int j=m+;j<=m<<;++j) G[i][j-m]=f[j];
} G=qpow(G,(ed-st+)/m-);
for(int i=;i<=m;++i) for(int j=;j<=m;++j)
cmax(ans,G[i][j]+lf[b[i]]+rf[b[j]]+);
return printf("%lld\n",ans),;
}

$D^2 \log D$

本来我用的是贪心,然后挂了,就用矩阵了,这里就放 std 的代码好了 Q.T

 #include<bits/stdc++.h>
using namespace std;
typedef long long int64;
const int maxn=,maxd=;
int a[maxn],b[maxn],pos[maxd];
int A,B,C,D,m; int64 st,ed,n; struct Tbinary_index_tree{
int t[maxd];
void clear(){ memset(t,,sizeof(t)); }
void insert(int x,int v){
for(int i=++x;i<maxd;i+=i&-i)
t[i]=max(t[i],v);
}
int query(int x){
int res=; ++x;
for(int i=x;i;i-=i&-i)
res=max(res,t[i]);
return res;
}
}bit;
void brute_force(){
scanf("%d%d%d%d%d",a+,&A,&B,&C,&D);
bit.clear(),bit.insert(a[],); int ans=;
for(int i=;i<=n;++i){
a[i]=(A*a[i-]*a[i-]+B*a[i-]+C)%D;
int f=bit.query(a[i])+;
bit.insert(a[i],f),ans=max(ans,f);
}
printf("%d\n",ans);
} void init(){
scanf("%d%d%d%d%d",a+,&A,&B,&C,&D);
memset(pos,-,sizeof(pos)),pos[a[]]=;
for(int i=;;++i){
a[i]=(A*a[i-]*a[i-]+B*a[i-]+C)%D;
if(pos[a[i]]!=-){ st=i,m=i-pos[a[i]]; break; }
pos[a[i]]=i;
}
ed=n-(n-st+)%m;
for(int i=st;i<=st+m*m-;++i)
a[i]=(A*a[i-]*a[i-]+B*a[i-]+C)%D;
b[]=a[st];
for(int i=;i<=n-ed+m*m;++i)
b[i]=(A*b[i-]*b[i-]+B*b[i-]+C)%D;
st+=m*m,ed-=m*m; assert(st<ed);
} int lf[maxd],rf[maxd],f[maxn];
void solve(){
memset(lf,,sizeof(lf));
memset(f,,sizeof(f)),bit.clear();
for(int i=;i<st;++i){
f[i]=bit.query(a[i])+;
bit.insert(a[i],f[i]);
lf[a[i]]=max(lf[a[i]],f[i]);
}
for(int i=;i<maxd;++i)
lf[i]=max(lf[i],lf[i-]);
memset(f,,sizeof(f)),bit.clear();
for(int i=n-ed;i>=;--i){
f[i]=bit.query(maxd-b[i]-)+;
bit.insert(maxd-b[i]-,f[i]);
rf[b[i]]=max(rf[b[i]],f[i]);
}
for(int i=maxd-;i>=;--i)
rf[i]=max(rf[i],rf[i+]);
int64 ans=;
for(int i=;i<=m;++i){
int v=a[st-m*m+i-];
ans=max(ans,lf[v]+(ed-st+)/m+rf[v]);
}
printf("%lld\n",ans);
} int main(){
freopen("lis.in","r",stdin);
freopen("lis.out","w",stdout);
scanf("%lld",&n);
if(n<=)
brute_force();
else init(),solve();
return ;
}

t2:

题意

给你 n 件物品来放完全背包,体积小于 L 的无限放, 大于等于 L 的物品总共最多放 C 件,然后给出多组询问,你需要判断是否能用这些物品在满足条件的情况下放满 W 大小的背包

分析

回到了被跳楼机支配的恐惧...

首先令最小的物品体积为 V ,那么这个物品是可以无限放的,所以我们只需要记录要达到在模 V 下的体积会放到的最小体积,然后判断的时候看 询问值模 V 后是否大于等于这个值就好了(因为多出来的体积可以用 V 补)

设计状态 $f[i][j][k]$ 为前 i 个物品中加入了 j 次体积不小于 L 的物品,且总体积模 V 为 k 的最小总体积 (我就觉得是跳楼机了)

然后刚刚我说的显然有错啊,最小物品的体积不见得就可以无限放,那么如果最小体积物品也 ≥ L ,那么最多放 C 件,直接暴力跑就能出解了,状态也比较简单,就是考虑放不超过 c 件物品能达到的体积,加上 vi 本来就小,随便套套 bitset (不套也行)就解决了

code

 //by Judge
#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int MV=,M=;
#define getchar() (p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<21,stdin),p1==p2)?EOF:*p1++)
char buf[<<],*p1,*p2;
inline void cmin(ll& a,ll b){if(a>b)a=b;}
inline ll read(){ ll x=,f=; char c=getchar();
for(;!isdigit(c);c=getchar()) if(c=='-') f=-;
for(;isdigit(c);c=getchar()) x=x*+c-''; return x*f;
} char sr[<<],z[]; int Z,C=-;
inline void Ot(){fwrite(sr,,C+,stdout),C=-;}
int n,m,v[M],V,V0,c;
ll f[][MV*],g[MV];
inline void preset(){
for(int j=;j<=c;++j) for(int k=;k<V;++k) f[j][k]=1e18; f[][]=;
for(int i=,t;i<=n;++i) if(v[i]>=V0){ t=v[i]%V;
for(int j=;j<=c;++j) for(int k=;k<V;++k)
cmin(f[j][k],f[j-][(k+V-t)%V]+v[i]);
} else{ int len=V/__gcd(v[i],V);
for(int j=;j<=c;++j) for(int N=V/len,d=;d<N;++d)
for(int T=;T<=;++T) for(int k=,las=d,now;k<=len;++k)
now=(las+v[i])%V,cmin(f[j][now],f[j][las]+v[i]),las=now;
} for(int i=;i<V;++i) g[i]=1e18;
for(int j=;j<=c;++j) for(int k=;k<V;++k) cmin(g[k],f[j][k]);
for(ll x;m;--m)
if(x=read(),g[x%V]>x) sr[++C]='N',sr[++C]='o',sr[++C]='\n';
else sr[++C]='Y',sr[++C]='e',sr[++C]='s',sr[++C]='\n';
return Ot();
}
int main(){
freopen("bag.in","r",stdin);
freopen("bag.out","w",stdout);
n=read(),m=read();
for(int i=;i<=n;++i) v[i]=read(); sort(v+,v++n);
return V=v[],V0=read(),c=read(),preset(),;
}

NOIP模拟赛10 题解的更多相关文章

  1. 【noip模拟赛10】奇怪的贸易 高精度

    描述 刚结束了CS战斗的小D又进入了EVE的游戏世界,在游戏中小D是一名商人,每天要做的事情就是在这里买东西,再运到那里去卖.这次小D来到了陌生的X星,X星上有n种货物,小D决定每种都买走一些,他用a ...

  2. NOIP模拟赛10

    T1 [HAOI2010]软件安装 https://daniu.luogu.org/problem/show?pid=2515 树上背包,如果有i必须有j,j作为i的父节点 O(nm²) #inclu ...

  3. contesthunter暑假NOIP模拟赛第一场题解

    contesthunter暑假NOIP模拟赛#1题解: 第一题:杯具大派送 水题.枚举A,B的公约数即可. #include <algorithm> #include <cmath& ...

  4. 大家AK杯 灰天飞雁NOIP模拟赛题解/数据/标程

    数据 http://files.cnblogs.com/htfy/data.zip 简要题解 桌球碰撞 纯模拟,注意一开始就在袋口和v=0的情况.v和坐标可以是小数.为保险起见最好用extended/ ...

  5. 10.17 NOIP模拟赛

    目录 2018.10.17 NOIP模拟赛 A 咒语curse B 神光light(二分 DP) C 迷宫maze(次短路) 考试代码 B 2018.10.17 NOIP模拟赛 时间:1h15min( ...

  6. 10.16 NOIP模拟赛

    目录 2018.10.16 NOIP模拟赛 A 购物shop B 期望exp(DP 期望 按位计算) C 魔法迷宫maze(状压 暴力) 考试代码 C 2018.10.16 NOIP模拟赛 时间:2h ...

  7. 队爷的讲学计划 CH Round #59 - OrzCC杯NOIP模拟赛day1

    题目:http://ch.ezoj.tk/contest/CH%20Round%20%2359%20-%20OrzCC杯NOIP模拟赛day1/队爷的讲学计划 题解:刚开始理解题意理解了好半天,然后发 ...

  8. CH Round #49 - Streaming #4 (NOIP模拟赛Day2)

    A.二叉树的的根 题目:http://www.contesthunter.org/contest/CH%20Round%20%2349%20-%20Streaming%20%234%20(NOIP 模 ...

  9. CH Round #54 - Streaming #5 (NOIP模拟赛Day1)

    A.珠 题目:http://ch.ezoj.tk/contest/CH%20Round%20%2354%20-%20Streaming%20%235%20(NOIP模拟赛Day1)/珠 题解:sb题, ...

随机推荐

  1. 细说java系列之泛型

    什么是范型 简言之,范型是Java支持在编译期进行类型检查的机制. 这里面包含2层含义:其一,可以使用范型进行类型检查:其二,在编译期进行类型检查. 那么,什么叫做在编译期进行类型检查?可以在运行时进 ...

  2. 十七、文件和目录——minishell(1)

    主函数运行要去读取从标准输入或终端上输入的整个命令行,然后再去解析命令行参数,解析出来之后,要将其封装成一个 program,然后再将 program 放入 job 中,然后再去执行 job 中的命令 ...

  3. Play XML Entities

    链接:https://pentesterlab.com/exercises/play_xxe/course Introduction This course details the exploitat ...

  4. gson和fastjson将json对象转换成javaBean 简单对照

    今天在网上看代码时,发现项目使用了Gson,用于将json字符串转换成javaBean. 以前没使用过Gson,随即,简单入了个们, 想起fastjson也有将json字符串转换成javaBean的A ...

  5. django设置并获取cookie/session,文件上传,ajax接收文件,post/get请求及跨域请求等的方法

    django设置并获取cookie/session,文件上传,ajax接收文件等的方法: views.py文件: from django.shortcuts import render,HttpRes ...

  6. LOJ #2587「APIO2018」铁人两项

    是不是$ vector$存图非常慢啊...... 题意:求数对$(x,y,z)$的数量使得存在一条$x$到$z$的路径上经过$y$,要求$x,y,z$两两不同  LOJ #2587 $ Solutio ...

  7. MySQL - GROUP BY和HAVING的用法

    按姓名分组查询 SELECT username, COUNT(username) AS '人数' FROM t_user GROUP BY username 只查询姓名相同的人 SELECT user ...

  8. python异常处理的两种写法

    (1)第一种写法 需要注意的是 在抛出异常的时候,HTTPError必须写在URLError之前,因为只有这样前者才能抛出异常,不然的话就会被后者拦截,提前抛出异常. from urllib.requ ...

  9. Nginx在局域网中使用ip_hash负载均衡策略,访问全部分发到同一个后台服务器

    Nginx的ip_hash算法都将一个ip地址的前三段作为hash的关键字

  10. tar命令加密压缩

    场景 Centos6下使用加密压缩,可以从A机器到B机器解压. 可用在kali上解压就不行. 命令 解包 tar zxvf FileName.tar 打包 tar czvf FileName.tar ...