并没有什么好说的。2019.4.5开始省选,在省选来临前把所有学过的算法不完全打了一边。希望省选能过个100分?(o?v?)ノ
R6板载!!
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <iostream>
#include <queue>
#include <cstdlib>
using namespace std;
typedef long long ll;
inline int read(){
char tmp=getchar(); int sum=0; bool flag=false;
while(tmp<‘0‘||tmp>‘9‘){
if(tmp==‘-‘) flag=true;
tmp=getchar();
}
while(tmp>=‘0‘&&tmp<=‘9‘){
sum=(sum<<3)+(sum<<1)+tmp-‘0‘;
tmp=getchar();
}
return flag?-sum:sum;
}
inline long long readll(){
char tmp=getchar(); long long sum=0; bool flag=false;
while(tmp<‘0‘||tmp>‘9‘){
if(tmp==‘-‘) flag=true;
tmp=getchar();
}
while(tmp>=‘0‘&&tmp<=‘9‘){
sum=(sum<<3)+(sum<<1)+tmp-‘0‘;
tmp=getchar();
}
return flag?-sum:sum;
}
// 快排
namespace quicksort{
const int MAX=1e6+6;
int n;
int num[MAX];
void qsort(int l,int r){
int mid=num[(l+r)>>1];
int x=l,y=r;
while(x<=y){
while(x<=y&&num[x]<mid) x++;
while(x<=y&&num[y]>mid) y--;
if(x<=y){
swap(num[x],num[y]);
x++; y--;
}
}
if(y>l) qsort(l,y);
if(x<r) qsort(x,r);
}
};
//并查集
namespace bcj{
const int MAX=1e4+5;
int n,m;
int fa[MAX];
void init(){
for(int i=1;i<=n;++i) fa[i]=i;
}
int getfa(int u){
if(fa[u]!=u) fa[u]=getfa(fa[u]);
return fa[u];
}
void unionn(int x,int y){
int fx=getfa(x),fy=getfa(y);
if(fx!=fy) fa[fx]=fy;
}
void cp(int x,int y){
int fx=getfa(x),fy=getfa(y);
if(fx!=fy) printf("N\n");
else printf("Y\n");
}
void debug(){
for(int i=1;i<=n;++i) printf("%d ",getfa(i));
printf("\n");
}
}
//快速幂
namespace qsm{
typedef long long ll;
ll b,p,k;
ll getqsm(ll b,ll p,ll k){
ll ans=1ll,base=b;
while(p){
if(p&1ll){
ans*=base;
ans%=k;
}
base*=base;
base%=k;
p>>=1ll;
}
return ans%k;
}
}
//欧拉线性筛
namespace prim{
const int MAX=10000000+500;
int n,m;
int prime[MAX],oula[MAX]; bool check[MAX];
void judge(){
for(int i=2;i<=n;++i){
if(!check[i]){
prime[++prime[0]]=i;
oula[i]=i-1;
}
for(int j=1;j<=prime[0]&&prime[j]*i<=n;++j){
check[i*prime[j]]=true;
oula[i*prime[j]]=oula[i]*oula[prime[j]];
if(i%prime[j]==0){
oula[i*prime[j]]=oula[i]*prime[j];
break;
}
}
}
}
}
//小根堆
namespace teap{
const int MAX=1e6+6;
int n,m;
int line[MAX];
void init(){
n=0;
}
void insert(int x){
n++; line[n]=x;
int u=n;
while(u!=1){
int v=(u>>1);
if(line[v]>line[u]){
swap(line[v],line[u]);
u=v;
}
else break;
}
}
int top(){
return line[1];
}
void pop(){
line[1]=line[n--];
int u=1;
while((u<<1)<=n){
int v=u<<1;
if(v<n&&line[v]>line[v+1]) v++;
if(line[u]<=line[v]) break;
else{
swap(line[u],line[v]);
u=v;
}
}
}
}
//最小生成树 (unfinished)
namespace MSTprim{
const int MAXN=5e3+5,MAXM=2e5+5,INF=0x3f3f3f3f;
int n,m;
int ecnt,edge[MAXM],head[MAXN],nxt[MAXM],w[MAXM];
int fir[MAXN],sec[MAXN];
bool in[MAXN];
int cnt,ans;
priority_queue <int> line;
void insert(int from,int to,int wei,int id){
nxt[id]=head[from]; head[from]=id; edge[id]=to; w[id]=wei;
}
void build(){
for(int u=1;u<=n;++u){
fir[u]=sec[u]=INF;
for(int i=head[u];i;i=nxt[i]){
int v=w[i];
if(v<fir[u]){
sec[u]=fir[u]; fir[u]=i;
}
else if(v<sec[u]){
sec[u]=i;
}
}
}
}
void getMST(){
cnt=1,ans=0;
in[1]=true;
line.push(fir[1]); line.push(sec[1]);
while(cnt<n||line.empty()){
int e=line.top(); line.pop();
while(in[edge[e]]){
if(!line.empty()) e=line.top(),line.pop();
else break;
}
if(line.empty()) break;
cout<<edge[e]<<endl;
in[edge[e]]=true;
line.push(fir[edge[e]]); line.push(sec[edge[e]]);
ans+=w[e];
}
}
}
//最大流
namespace zuidaliu{
const int MAXN=2e4+5,MAXM=3e5+5,INF=0x3f3f3f3f;
int n,m,src,tar;
int ecnt,edge[MAXM],head[MAXN],nxt[MAXM],w[MAXM];
int dep[MAXN],cur[MAXN];
void init(){
ecnt=1;
}
void insert(int from,int to,int wei,int id){
nxt[id]=head[from]; head[from]=id; edge[id]=to; w[id]=wei;
}
bool bfs(){
queue <int> line;
memset(dep,0,sizeof(dep)); dep[src]=1;
line.push(src);
while(!line.empty()){
int u=line.front(); line.pop();
for(int i=head[u];i;i=nxt[i]){
int v=edge[i]; if(!w[i]||dep[v]) continue;
dep[v]=dep[u]+1;
line.push(v);
}
}
if(dep[tar]){
for(int i=1;i<=n;++i) cur[i]=head[i];
return true;
}
else return false;
}
int dfs(int u,int flow){
if(u==tar||!flow) return flow;
int ans=0;
for(int i=cur[u];i;i=nxt[i]){
cur[u]=i;
int v=edge[i]; if(dep[v]!=dep[u]+1) continue;
int tmp=dfs(v,min(w[i],flow));
if(tmp){
flow-=tmp;
ans+=tmp;
w[i]-=tmp;
w[i^1]+=tmp;
}
}
return ans;
}
int maxflow(){
int ans=0;
while(bfs()) ans+=dfs(src,INF);
return ans;
}
}
//费用流 (未通过)
namespace feiyongliu{
const int MAXN=5e3+50,MAXM=1e5+50,INF=0x3f3f3f3f;
int n,m,src,tar;
int ecnt,edge[MAXM],head[MAXN],nxt[MAXM],w[MAXM],c[MAXM];
int maxflow,mincost,dis[MAXN],flow[MAXN],pre[MAXN]; bool vis[MAXN];
void init(){
ecnt=1;
}
void insert(int from,int to,int wei,int co,int id){
nxt[id]=head[from]; head[from]=id; edge[id]=to; w[id]=wei; c[id]=co;
}
bool spfa(){
memset(flow,INF,sizeof(flow));
memset(dis,INF,sizeof(dis)); dis[src]=0;
memset(vis,0,sizeof(vis));
memset(pre,-1,sizeof(pre));
queue <int> line; line.push(src);
while(!line.empty()){
int u=line.front(); line.pop();
for(int i=head[u];i;i=nxt[i]){
int v=edge[i];
if(w[i]&&dis[v]>dis[u]+c[i]){
dis[v]=dis[u]+c[i];
flow[v]=min(flow[u],w[i]);
pre[v]=i;
if(!vis[v]){
vis[v]=true;
line.push(v);
}
}
}
}
return pre[tar]!=-1;
}
int mcmf(){
int ans=0;
while(spfa()){
maxflow+=flow[tar];
mincost+=flow[tar]*dis[tar];
int u=tar;
while(u!=src){
w[pre[u]]-=flow[tar];
w[pre[u]^1]+=flow[tar];
u=edge[pre[u]^1];
}
}
return ans;
}
}
//tarjan
namespace suodian{
const int MAXN=1e4+50,MAXM=1e5+50,INF=0x3f3f3f3f;
int n,m;
int valua[MAXN];
int ecnt,edge[MAXM],head[MAXN],nxt[MAXM];
int tim,stack[MAXN],DFN[MAXN],LOW[MAXN]; bool vis[MAXN];
int col;
void insert(int from,int to,int id){
nxt[id]=head[from]; head[from]=id; edge[id]=to;
}
void tarjan(int u){
DFN[u]=LOW[u]=++tim;
stack[++stack[0]]=u;
vis[u]=true;
for(int i=head[u];i;i=nxt[i]){
int v=edge[i];
if(!DFN[v]){
tarjan(v);
LOW[u]=min(LOW[u],LOW[v]);
}
else if(vis[v]){
LOW[u]=min(LOW[u],DFN[v]);
}
}
if(DFN[u]==LOW[u]){
col++;
while(stack[stack[0]]!=u) stack[0]--;
stack[0]--;
}
}
}
// 矩阵快速幂
namespace matrixtime{
static const int MAX=1e2+5,MOD=1e9+7;
int n; ll k;
struct matrix{
int x,y;
ll num[MAX][MAX];
matrix operator * (const matrix &n) const{
matrix tmp;
tmp.x=x; tmp.y=n.y;
for(int i=1;i<=tmp.x;++i){
for(int j=1;j<=tmp.y;++j){
tmp.num[i][j]=0;
}
}
for(int i=1;i<=x;++i){
for(int j=1;j<=n.y;++j){
for(int k=1;k<=y;++k){
tmp.num[i][j]+=num[i][k]*n.num[k][j];
tmp.num[i][j]%=MOD;
}
}
}
return tmp;
}
void print(){
for(int i=1;i<=x;++i){
for(int j=1;j<=y;++j){
printf("%lld ",num[i][j]);
}
printf("\n");
}
}
}input,output;
matrix qsm(matrix u,ll k){
matrix ans,base;
ans.x=u.x; ans.y=u.y;
for(int i=1;i<=ans.x;++i){
ans.num[i][i]=1ll;
}
base=u;
while(k){
if(k&1ll){
ans=ans*base;
}
base=base*base;
k>>=1;
}
return ans;
}
void work(){
n=read(); k=readll();
input.x=n; input.y=n;
for(int i=1;i<=n;++i){
for(int j=1;j<=n;++j){
input.num[i][j]=readll();
}
}
output=qsm(input,k);
output.print();
}
}
//线段树1
namespace segmenttree1{
const int MAX=1e5+5;
int n,m;
ll sum[MAX<<2],lazy[MAX<<2];
ll pre[MAX];
void build(int l,int r,int id){
if(l==r){
sum[id]=pre[l];
return;
}
int mid=(l+r)>>1;
build(l,mid,(id<<1));
build(mid+1,r,(id<<1)+1);
sum[id]=sum[(id<<1)]+sum[(id<<1)+1];
}
void add(int l,int r,int id,ll k){
lazy[id]+=k;
sum[id]+=(r-l+1)*k;
}
void pushdown(int l,int r,int id){
if(!lazy[id]) return;
int mid=(l+r)>>1;
add(l,mid,(id<<1),lazy[id]);
add(mid+1,r,(id<<1)+1,lazy[id]);
lazy[id]=0;
}
void modify(int l,int r,int id,int L,int R,ll k){
if(L<=l&&r<=R) return add(l,r,id,k);
pushdown(l,r,id);
int mid=(l+r)>>1;
if(L<=mid) modify(l,mid,(id<<1),L,R,k);
if(R>=mid+1) modify(mid+1,r,(id<<1)+1,L,R,k);
sum[id]=sum[(id<<1)]+sum[(id<<1)+1];
}
ll getsum(int l,int r,int id,int L,int R){
if(L<=l&&R>=r) return sum[id];
pushdown(l,r,id);
ll ans=0,mid=(l+r)>>1;
if(L<=mid) ans+=getsum(l,mid,(id<<1),L,R);
if(R>=mid+1) ans+=getsum(mid+1,r,(id<<1)+1,L,R);
return ans;
}
void init(){
for(int i=1;i<=n;++i) pre[i]=read();
build(1,n,1);
}
void debug(int t){
cout<<"time: "<<t<<endl;
for(int i=1;i<=n;++i) printf("%lld ",getsum(1,n,1,i,i));
printf("\n");
}
void work(){
n=read(); m=read();
init();
for(int i=1;i<=m;++i){
int type,x,y; ll k; type=read();
switch(type){
case 1:
x=read(); y=read(); k=readll();
modify(1,n,1,x,y,k);
break;
case 2:
x=read(); y=read();
printf("%lld\n",getsum(1,n,1,x,y));
break;
}
// debug(i);
}
}
}
//线段树2
namespace segmenttree2{
const int MAX=2e5+5;
int n,m;
ll pre[MAX],sum[MAX<<2],lazy_add[MAX<<2],lazy_time[MAX<<2],P;
void build(int l,int r,int id){
lazy_time[id]=1;
if(l==r){
sum[id]=pre[l];
sum[id]=(sum[id]%P+P)%P;
return;
}
int mid=(l+r)>>1;
build(l,mid,(id<<1));
build(mid+1,r,(id<<1)+1);
sum[id]=sum[(id<<1)]+sum[(id<<1)+1];
sum[id]=(sum[id]%P+P)%P;
}
void add(int l,int r,int id,ll k,ll m){
lazy_add[id]=lazy_add[id]*m+k;
lazy_add[id]=(lazy_add[id]%P+P)%P;
lazy_time[id]*=m;
lazy_time[id]=(lazy_time[id]%P+P)%P;
sum[id]=sum[id]*m+(r-l+1)*k;
sum[id]=(sum[id]%P+P)%P;
}
void pushdown(int l,int r,int id){
if(lazy_add[id]==0&&lazy_time[id]==1) return;
int mid=(l+r)>>1;
add(l,mid,(id<<1),lazy_add[id],lazy_time[id]);
add(mid+1,r,(id<<1)+1,lazy_add[id],lazy_time[id]);
lazy_add[id]=0; lazy_time[id]=1;
}
void modify_add(int l,int r,int id,int L,int R,ll k){
if(L<=l&&r<=R) return add(l,r,id,k,1);
pushdown(l,r,id);
int mid=(l+r)>>1;
if(L<=mid) modify_add(l,mid,(id<<1),L,R,k);
if(R>=mid+1) modify_add(mid+1,r,(id<<1)+1,L,R,k);
sum[id]=sum[(id<<1)]+sum[(id<<1)+1];
sum[id]=(sum[id]%P+P)%P;
}
void modify_time(int l,int r,int id,int L,int R,ll k){
if(L<=l&&r<=R) return add(l,r,id,0,k);
pushdown(l,r,id);
int mid=(l+r)>>1;
if(L<=mid) modify_time(l,mid,(id<<1),L,R,k);
if(R>=mid+1) modify_time(mid+1,r,(id<<1)+1,L,R,k);
sum[id]=sum[(id<<1)]+sum[(id<<1)+1];
sum[id]=(sum[id]%P+P)%P;
}
ll getsum(int l,int r,int id,int L,int R){
if(L<=l&&R>=r) return sum[id];
pushdown(l,r,id);
ll ans=0,mid=(l+r)>>1;
if(L<=mid) ans+=getsum(l,mid,(id<<1),L,R);
if(R>=mid+1) ans+=getsum(mid+1,r,(id<<1)+1,L,R);
return (ans%P+P)%P;
}
void init(){
for(int i=1;i<=n;++i) pre[i]=readll();
build(1,n,1);
}
void debug(int t){
cout<<"time: "<<t<<endl;
for(int i=1;i<=n;++i) printf("%lld ",getsum(1,n,1,i,i));
printf("\n");
}
void work(){
n=read(); m=read(); P=readll();
init();
for(int i=1;i<=m;++i){
int type,x,y; ll k; type=read();
switch(type){
case 1:
x=read(); y=read(); k=readll();
modify_time(1,n,1,x,y,k);
break;
case 2:
x=read(); y=read(); k=readll();
modify_add(1,n,1,x,y,k);
break;
case 3:
x=read(); y=read();
printf("%lld\n",getsum(1,n,1,x,y));
break;
}
}
}
}
//树链剖分
namespace treedivider{
const int MAX=1e5+5;
int n,m,root;
ll sum[MAX<<2],lazy[MAX<<2],pre[MAX],MOD;
int ecnt,edge[MAX<<1],head[MAX],nxt[MAX<<1];
int fa[MAX],size[MAX],dep[MAX],son[MAX],top[MAX],seg[MAX],rev[MAX];
void insert(int from,int to,int id){
nxt[id]=head[from]; head[from]=id; edge[id]=to;
}
void dfs1(int u,int f){
fa[u]=f;
dep[u]=dep[f]+1;
for(int i=head[u];i;i=nxt[i]){
int v=edge[i]; if(v==f) continue;
fa[v]=u;
dfs1(v,u);
size[u]+=size[v];
if(size[v]>size[son[u]]){
son[u]=v;
}
}
size[u]++;
}
void dfs2(int u,int f){
if(son[u]){
int v=son[u];
top[v]=top[u];
seg[v]=++seg[0];
rev[seg[0]]=v;
dfs2(v,u);
}
for(int i=head[u];i;i=nxt[i]){
int v=edge[i]; if(v==son[u]||v==f) continue;
top[v]=v;
seg[v]=++seg[0];
rev[seg[0]]=v;
dfs2(v,u);
}
}
void build(int l,int r,int id){
if(l==r){
sum[id]=pre[rev[l]];
return;
}
int mid=(l+r)>>1;
build(l,mid,(id<<1));
build(mid+1,r,(id<<1)+1);
sum[id]=sum[(id<<1)]+sum[(id<<1)+1];
}
void add(int l,int r,int id,ll k){
lazy[id]+=k;
lazy[id]=(lazy[id]%MOD+MOD)%MOD;
sum[id]+=(r-l+1)*k;
sum[id]=(sum[id]%MOD+MOD)%MOD;
}
void pushdown(int l,int r,int id){
if(!lazy[id]) return;
int mid=(l+r)>>1;
add(l,mid,(id<<1),lazy[id]);
add(mid+1,r,(id<<1)+1,lazy[id]);
lazy[id]=0;
}
void modify(int l,int r,int id,int L,int R,ll k){
if(L<=l&&r<=R) return add(l,r,id,k);
pushdown(l,r,id);
int mid=(l+r)>>1;
if(L<=mid) modify(l,mid,(id<<1),L,R,k);
if(R>=mid+1) modify(mid+1,r,(id<<1)+1,L,R,k);
sum[id]=sum[(id<<1)]+sum[(id<<1)+1];
sum[id]=(sum[id]%MOD+MOD)%MOD;
}
ll getsum(int l,int r,int id,int L,int R){
if(L<=l&&R>=r) return sum[id];
pushdown(l,r,id);
ll ans=0,mid=(l+r)>>1;
if(L<=mid) ans+=getsum(l,mid,(id<<1),L,R);
if(R>=mid+1) ans+=getsum(mid+1,r,(id<<1)+1,L,R);
return (ans%MOD+MOD)%MOD;
}
ll qsum(int x,int y){
ll ans=0;
int fx=top[x],fy=top[y];
while(fx!=fy){
if(dep[fx]<dep[fy]) swap(x,y),swap(fx,fy);
ans+=getsum(1,n,1,seg[fx],seg[x]);
ans=(ans%MOD+MOD)%MOD;
x=fa[fx]; fx=top[x];
}
if(dep[x]>dep[y]) swap(x,y);
ans+=getsum(1,n,1,seg[x],seg[y]);
return ans%MOD;
}
void qplus(int x,int y,ll k){
int fx=top[x],fy=top[y];
while(fx!=fy){
if(dep[fx]<dep[fy]) swap(x,y),swap(fx,fy);
modify(1,n,1,seg[fx],seg[x],k);
x=fa[fx]; fx=top[x];
}
if(dep[x]>dep[y]) swap(x,y);
modify(1,n,1,seg[x],seg[y],k);
}
void debug(int t){
cout<<"time: "<<t<<endl;
for(int i=1;i<=n;++i) printf("%lld ",getsum(1,n,1,i,i));
printf("\n");
}
void work(){
n=read(); m=read(); root=read(); MOD=readll();
for(int i=1;i<=n;++i) pre[i]=readll();
for(int i=1;i<n;++i){
int u,v; u=read(); v=read();
insert(u,v,++ecnt); insert(v,u,++ecnt);
}
dfs1(root,root);
top[root]=root;
seg[root]=++seg[0];
rev[seg[0]]=root;
dfs2(root,root);
build(1,n,1);
for(int i=1;i<=m;++i){
int type,x,y; ll z; type=read();
switch(type){
case 1:
x=read(); y=read(); z=readll();
qplus(x,y,z);
break;
case 2:
x=read(); y=read();
printf("%lld\n",qsum(x,y));
break;
case 3:
x=read(); z=readll();
modify(1,n,1,seg[x],seg[x]+size[x]-1,z);
break;
case 4:
x=read();
printf("%lld\n",getsum(1,n,1,seg[x],seg[x]+size[x]-1));
break;
}
}
}
}
//treap平衡树
namespace balancetree{
static const int MAX=1e5+5;
int root,pool;
int val[MAX],lson[MAX],rson[MAX],pri[MAX],cnt[MAX],size[MAX];
void zag(int &u){
int v=lson[u];
lson[u]=rson[v];
rson[v]=u;
size[v]=size[u];
size[u]=size[lson[u]]+size[rson[u]]+cnt[u];
u=v;
}
void zig(int &u){
int v=rson[u];
rson[u]=lson[v];
lson[v]=u;
size[v]=size[u];
size[u]=size[lson[u]]+size[rson[u]]+cnt[u];
u=v;
}
void insert(int &u,int k){
if(!u){
u=++pool; size[u]=1; cnt[u]=1; val[u]=k; pri[u]=rand();
lson[u]=rson[u]=0;
return;
}
size[u]++;
if(val[u]==k){
cnt[u]++;
}
else if(val[u]>k){
insert(lson[u],k);
if(pri[lson[u]]>pri[u]) zag(u);
}
else{
insert(rson[u],k);
if(pri[rson[u]]>pri[u]) zig(u);
}
}
void del(int &u,int k){
if(val[u]==k){
if(cnt[u]>1) cnt[u]--,size[u]--;
else if(!lson[u]||!rson[u]) u=lson[u]+rson[u];
else if(pri[lson[u]]<pri[rson[u]]) zag(u),del(u,k);
else zig(u),del(u,k);
return;
}
size[u]--;
if(val[u]>k) del(lson[u],k);
else del(rson[u],k);
}
bool exist(int k){
int u=root;
while(u){
if(val[u]==k) return true;
else if(val[u]>k) u=lson[u];
else u=rson[u];
}
return false;
}
int rand(int k){
int tot=0,u=root;
while(u){
if(val[u]==k){
return tot+size[lson[u]]+1;
}
else if(val[u]>k){
u=lson[u];
}
else{
tot+=size[lson[u]]+cnt[u];
u=rson[u];
}
}
}
int xth(int k){
int tot=0,u=root;
while(u){
if(tot+size[lson[u]]+1<=k&&k<=tot+size[lson[u]]+cnt[u]) return val[u];
else if(k<tot+size[lson[u]]+1) u=lson[u];
else{
tot+=size[lson[u]]+cnt[u];
u=rson[u];
}
}
}
void work(){
for(int i=1;i<=10;++i) printf("%d ",exist(i)); puts("");
for(int i=10;i>=1;--i) insert(root,i);
for(int i=1;i<=10;++i) printf("%d ",exist(i)); puts("");
del(root,3);
for(int i=1;i<=10;++i) printf("%d ",exist(i)); puts("");
for(int i=1;i<=10;++i) printf("%d ",rand(i)); puts("");
for(int i=1;i<=9;++i) printf("%d ",xth(i));
}
}
int main(){
freopen("test.in","r",stdin);
using namespace balancetree;
work();
return 0;
}
tada~~ 回头看看,还是学了不少的( ̄︶ ̄)↗
原文:https://www.cnblogs.com/ticmis/p/13210515.html