csps-模拟7980题解
题面:https://www.cnblogs.com/Juve/articles/11712702.html
树:
我太sb了不知道DROT是1,还在sb找根
记录一个fa[]数组,表示x的祖先中第一个智商比x大的,用栈维护
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define re register
using namespace std;
const int MAXN=1e5+;
int n,q,w[MAXN],sta[MAXN],top=,rb[MAXN],topp=,fa[MAXN],deep[MAXN];
int to[MAXN<<],nxt[MAXN<<],pre[MAXN],cnt=;
inline void add(re int u,re int v){
++cnt,to[cnt]=v,nxt[cnt]=pre[u],pre[u]=cnt;
}
void dfs(int x,int f){
deep[x]=deep[f]+;
int res=;
while(w[x]>w[sta[top]]){
rb[++topp]=sta[top];
--top,++res;
}
fa[x]=sta[top];
sta[++top]=x;
for(int i=pre[x];i;i=nxt[i]){
int y=to[i];
if(y==f) continue;
dfs(y,x);
}
--top;
while(res){
sta[++top]=rb[topp--];
--res;
}
}
signed main(){
scanf("%d%d",&n,&q);
for(re int i=;i<=n;++i) scanf("%d",&w[i]);
for(re int i=,u,v;i<n;++i){
scanf("%d%d",&u,&v);
add(u,v),add(v,u);
}
w[]=0x7fffffff;sta[++top]=;
dfs(,);
for(re int i=,u,v,c,res;i<=q;++i){
scanf("%d%d%d",&u,&v,&c);
res=;
if(c<w[u]) c=w[u],++res;
while(deep[u]>=deep[v]){
if(c<w[u]) c=w[u],++res;
u=fa[u];
}
if(c<w[v]) ++res;
printf("%d\n",res);
}
return ;
}
环:
我没脸抄的方程
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define int long long
using namespace std;
const int MAXN=1e5+,mod=1e9+;
int n,e,p[MAXN],q[MAXN],ans;
int q_pow(int a,int b,int p){
int res=;
while(b){
if(b&) res=res*a%p;
a=a*a%p;
b>>=;
}
return res;
}
signed main(){
scanf("%lld%lld",&n,&e);
for(int i=;i<=n;++i) q[i]=n-;
for(int i=,u,v;i<=e;++i){
scanf("%lld%lld",&u,&v);
++p[u],--q[u],--q[v];
}
ans=n*(n-)%mod*(n-)%mod*q_pow(,mod-,mod)%mod;
for(int i=;i<=n;++i){
int res=p[i]*(p[i]-)%mod*q_pow(,mod-,mod)%mod+p[i]*q[i]%mod*q_pow(,mod-,mod)%mod+q[i]*(q[i]-)%mod*q_pow(,mod-,mod)%mod;
ans=(ans-res+mod)%mod;
}
printf("%lld\n",ans);
return ;
}
礼物:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define int long long
#define re register
using namespace std;
const int mod=1e9+,MAXN=1e7+,MAXM=1e7+;
int n,a[MAXN],b[MAXN],ans;
inline int q_pow(re int a,re int b,re int p){
int res=;
while(b){
if(b&) res=res*a%p;
a=a*a%p;
b>>=;
}
return res;
}
int fac[MAXM<<],inv[MAXM<<];
inline void get_c(re int N){
fac[]=fac[]=inv[]=;
for(int i=;i<=N;++i) fac[i]=fac[i-]*i%mod;
inv[N]=q_pow(fac[N],mod-,mod);
for(int i=N-;i>=;--i) inv[i]=inv[i+]*(i+)%mod;
}
inline int C(re int n,re int m){
if(m>n) return ;
if(n==m) return ;
return fac[n]*inv[m]%mod*inv[n-m]%mod;
}
int maxx=,tong[MAXM<<],bas=1e7+;
signed main(){
scanf("%lld",&n);
for(re int i=;i<=n;++i){
scanf("%lld%lld",&a[i],&b[i]);
maxx=max(maxx,a[i]+b[i]);
}
get_c(maxx*+);
for(int i=;i<=n;++i){
for(int t=-a[i];t<=b[i];++t) ans=(ans+tong[t+bas]*C(a[i]+b[i],a[i]+t)%mod)%mod;
for(int t=-b[i];t<=a[i];++t) tong[t+bas]=(tong[t+bas]+C(a[i]+b[i],a[i]-t))%mod;
}
printf("%lld\n",*ans%mod);
return ;
}
最长不下降子序列:
n有1e12,但值域150,发现它是循环的,处理循环节即可
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define int long long
using namespace std;
const int MAXN=1e6+;
int n,t,a,b,c,d,p[MAXN],ans=,maxx=,cc[MAXN];
int lowbit(int x){
return x&(-x);
}
void update(int pos,int val){
for(int i=pos;i<=maxx;i+=lowbit(i)){
cc[i]=max(cc[i],val);
}
}
int query(int pos){
int res=;
for(int i=pos;i>;i-=lowbit(i)){
res=max(res,cc[i]);
}
return res;
}
int vis[MAXN];
signed main(){
scanf("%lld%lld%lld%lld%lld%lld",&n,&t,&a,&b,&c,&d);
if(n<=){
p[]=maxx=t;
for(int i=;i<=n;++i){
p[i]=(p[i-]*p[i-]%d*a%d+b*p[i-]%d+c%d)%d;
maxx=max(p[i],maxx);
}
++maxx;
for(int i=;i<=n;++i){
int res=query(p[i]+)+;
update(p[i]+,res);
ans=max(ans,res);
}
printf("%lld\n",ans);
return ;
}
p[]=maxx=t;
vis[t]=;
int pos=,q=;//q:xunhuanchangdu
for(int i=;i<=n;++i){
p[i]=(p[i-]*p[i-]%d*a%d+b*p[i-]%d+c%d)%d;
maxx=max(p[i],maxx);
if(vis[p[i]]){
pos=i;
q=i-vis[p[i]];
break;
}
vis[p[i]]=i;
}
++maxx;
if(!pos){
//cout<<pos<<endl;
for(int i=;i<=n;++i){
int res=query(p[i]+)+;
update(p[i]+,res);
ans=max(ans,res);
}
printf("%lld\n",ans);
return ;
}else{
int len=n-vis[p[pos]]+;
int xh=len/q;//xunhuanjici
int ys=len%q;//yuji
for(int i=;i<=pos-;++i){
int res=query(p[i]+)+;
update(p[i]+,res);
ans=max(ans,res);
}
for(int k=;k<=q;++k){
for(int i=pos;i<=min(n,pos+q-);++i){
p[i]=p[i-q];
int res=query(p[i]+)+;
update(p[i]+,res);
int tmp=i-pos+;
res=res+xh-k-+(tmp<=ys);
ans=max(ans,res);
}
pos=pos+q;
}
printf("%lld\n",ans);
return ;
}
return ;
}
完全背包问题:
同余系最短路,咕咕
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>
#define int long long
using namespace std;
const int MAXN=;
int n,m,l,c,v[MAXN],pos,minn=0x3f3f3f3f3f3f3f3f;
int dis[],cnt[];
queue<int>q;
bool in[];
void spfa(){
memset(dis,0x3f,sizeof(dis));
memset(cnt,0x3f,sizeof(cnt));
dis[]=cnt[]=;
in[]=;
q.push();
while(!q.empty()){
int x=q.front();
q.pop();
in[x]=;
for(int i=;i<=n;++i){
int y=(x+v[i])%minn;
if(v[i]>=l&&cnt[x]>=c) break;
if(dis[y]>dis[x]+v[i]){
dis[y]=dis[x]+v[i];
if(v[i]>=l) cnt[y]=cnt[x]+;
if(!in[y]) q.push(y),in[y]=;
}else if(dis[y]==dis[x]+v[i]){
if(cnt[y]>cnt[x]+(v[i]>l)){
cnt[y]=cnt[x]+;
if(!in[y]) q.push(y),in[y]=;
}
}
}
}
}
signed main(){
scanf("%lld%lld",&n,&m);
for(int i=;i<=n;++i){
scanf("%lld",&v[i]);
minn=min(minn,v[i]);
}
scanf("%lld%lld",&l,&c);
sort(v+,v+n+);
spfa();
for(int i=,x;i<=m;++i){
scanf("%lld",&x);
if(dis[x%minn]<=x) puts("Yes");
else puts("No");
}
return ;
}
最近公共祖先:
想到了正解,但不会维护subtree(fa[x])-subtree(x)的信息
考虑dfs序,更新时减去子树x即可
重复染的点可以直接break
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define int long long
using namespace std;
const int MAXN=1e5+;
int n,m,w[MAXN];
bool vis[MAXN];
int to[MAXN<<],nxt[MAXN<<],pre[MAXN],cnt=;
void add(int u,int v){
++cnt,to[cnt]=v,nxt[cnt]=pre[u],pre[u]=cnt;
}
int in[MAXN],out[MAXN],fa[MAXN],dfn=;
void dfs(int x){
in[x]=++dfn;
for(int i=pre[x];i;i=nxt[i]){
int y=to[i];
if(y==fa[x]) continue;
fa[y]=x;
dfs(y);
}
out[x]=dfn;
}
int tr[MAXN<<],laz[MAXN<<];
void down(int k){
tr[k<<]=max(tr[k<<],laz[k]);
tr[k<<|]=max(tr[k<<|],laz[k]);
laz[k<<]=max(laz[k<<],laz[k]);
laz[k<<|]=max(laz[k<<|],laz[k]);
laz[k]=;
}
void update(int k,int l,int r,int opl,int opr,int val){
if(opl<=l&&r<=opr){
tr[k]=max(tr[k],val);
laz[k]=max(laz[k],val);
return ;
}
if(laz[k]) down(k);
int mid=(l+r)>>;
if(opl<=mid) update(k<<,l,mid,opl,opr,val);
if(opr>mid) update(k<<|,mid+,r,opl,opr,val);
tr[k]=max(tr[k<<],tr[k<<|]);
}
int query(int k,int l,int r,int opt){
if(l==r) return tr[k];
if(laz[k]) down(k);
int mid=(l+r)>>;
if(opt<=mid) return query(k<<,l,mid,opt);
else return query(k<<|,mid+,r,opt);
}
signed main(){
scanf("%lld%lld",&n,&m);
for(int i=;i<=n;++i){
scanf("%lld",&w[i]);
}
for(int i=,u,v;i<n;++i){
scanf("%lld%lld",&u,&v);
add(u,v),add(v,u);
}
dfs(),vis[]=;
for(int i=;i<=m;++i){
char opt[];
int v,ans;
scanf("%s%lld",opt,&v);
if(opt[]=='M'){
update(,,n,in[v],out[v],w[v]);
vis[v]=;
while(vis[fa[v]]!=){
update(,,n,in[fa[v]],in[v]-,w[fa[v]]);
update(,,n,out[v]+,out[fa[v]],w[fa[v]]);
v=fa[v];
}
}else{
ans=query(,,n,in[v]);
if(!ans) ans=-;
printf("%lld\n",ans);
}
}
return ;
}
csps-模拟7980题解的更多相关文章
- CSP-S 模拟53 题解
题解: T1 u: 一看到修改这么多,但询问其实只有一个不难想到差分,但是他这个形状可以说很不规则,于是我们想到分别维护竖着的和斜着的差分,然后最后合并即可. 考场上瞎调了一波系数莫名AC,其实是维护 ...
- csp-s模拟99题解
题面:https://www.cnblogs.com/Juve/articles/11791219.html 上来先看T1,发现和之前做过的treap一样,是线段树维护单调栈,然后打了一个小时,然后它 ...
- csp-s模拟9697题解
题面:https://www.cnblogs.com/Juve/articles/11790223.html 96: 刚一看以为是水题,直接等差数列求和就好了,然后发现模数不是质数,还要1e18*1e ...
- CSP-S模拟68 题解
T1: 不难想到贪心,但是怎么贪,他有两个限制条件,所以不是很好搞,所以用一个类似与wqs二分的思路我可能在口胡,因为你肯定要把最小的给删掉,所以你限定一个x或y,然后在选出另一个限制,所以要同时维护 ...
- 反省——关于csp-s模拟50
本人于搜索csp-s模拟49题解时,有意识地点开了一篇关于csp-s模拟50T2的题解,并知道了题解是二维前缀和以及四维偏序. 更重要的是,那篇博客说有解法二,叫二维莫队. 于是我上网搜索二维莫队,结 ...
- csp-s模拟测试97
csp-s模拟测试97 猿型毕露.水题一眼秒,火题切不动,还是太菜了. $T1$看了一会儿感觉$woc$期望题$T1??$假的吧??. $T2$秒. $T3$什么玩意儿. 40 01:24:46 00 ...
- csp-s模拟测试87
csp-s模拟测试87 考场状态还可以$T1$我当时以为我秒切,$T2$确认自己思路不对后毅然决然码上,$T3$暴力挂了太可惜了. 03:01:28 03:16:07 03:11:38 140 03: ...
- csp-s模拟测试80(b)
csp-s模拟测试80(b) 水题没什么可写的. $T1SB$规律题正解调了仨小时就过了. $T2SBDp$题颓完题解就秒了. $T3SB$数据结构考场想到正解就弃了,考后太懒一半正解一发随机化就A了 ...
- [CQOI2012]模拟工厂 题解(搜索+贪心)
[CQOI2012]模拟工厂 题解(搜索+贪心) 标签:题解 阅读体验:https://zybuluo.com/Junlier/note/1327574 链接题目地址:洛谷P3161 BZOJ P26 ...
- csp-s模拟测试99
csp-s模拟测试99 九九归一直接爆炸. $T1$一眼板子. $T2$一眼语文题(语文的唯一一次$120+$是给模拟出来的可知我的语文能力). $T3$一眼普及题. ?? Hours Later 板 ...
随机推荐
- 22-8-filter
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- 2018-2-13-win10-uwp-让焦点在点击在页面空白处时回到textbox中
title author date CreateTime categories win10 uwp 让焦点在点击在页面空白处时回到textbox中 lindexi 2018-2-13 17:23:3 ...
- linux 下无法输入# 显示为£
在键盘布局里面,(Keyboard Layout)设置为中国,汉语.解决问题
- Ubuntu桌面突然卡住,图形界面无反应
1.可能等待几分钟,系统会自动反应过来.你可以选择等待几分钟. 2.绝大多数情况系统是不会反应过来的,这时候可以进入tty终端直接注销用户. (1)Ubuntu有6个tty终端,按住Ctrl+Alt+ ...
- IOS 表单含有input框和有position: fixed导致错位的问题
在input框聚焦失焦的时候,都调用以下js即可 setScrollTop() { let scrollTop = document.body.scrollTop + document.documen ...
- laravel passport client_credentials
我是使用 Laravel 5.4 + Dingo Api + passport/jwt 两个验证方式 目前需要用到 passport 的 client_credentials 获取 token成功之后 ...
- EF批量添加
1.首先,打开工具——NuGet包管理器——管理解决方案的NoGet程序包——搜索Z.EntityFramework.Extensions 点击安装!!! codefirst定义一个实体,用EF的方法 ...
- bzoj1009题解
[解题思路] 先KMP出fail数组,再用fail数组求出M[i][j],表示上一次匹配到第i位,这次可以遇到多少种不同的字符,使之转而匹配到第j位. 设集合S=[1,m]∩N 又设f[i][j]表示 ...
- NX二次开发-NXOpen方式遍历所有体workPart->Bodies();
NX11+VS2013 #include <NXOpen/DisplayManager.hxx> #include <NXOpen/Body.hxx> #include < ...
- hdu多校第七场 1011 (hdu6656) Kejin Player 概率dp
题意: 一个游戏,有许多关,到下一关要花费金钱,做出尝试,有概率成功,若成功则到达下一关,若失败则停在此关或退回到前面某关,询问第l关到第r关的期望费用 题解: 显然,第r关到第l关的费用是dp[r] ...