对拍&数据生成器
树生成器
#include<bits/stdc++.h>
using namespace std;
const int mod=1e9;
const int N=1e6+5;
int n,m=10;
int d[N],p[N];
vector<pair<int,int>> a;
int main(){
// freopen("in","w",stdout);
n=10;
mt19937 rnd(time(0));
for(int i=1;i<=n;++i){
d[i]=1;
}
for(int i=1;i<=n-2;++i){
++d[p[i]=rnd()%n+1];
}
int now,pre;
for(int i=1;i<=n;++i){
if(d[i]==1){
pre=now=i;
break;
}
}
for(int i=1;i<=n-2;++i){
int f=p[i];
a.push_back({now,f});
if(--d[f]==1&&f<pre){
now=f;
}
else{
while(d[++pre]!=1);
now=pre;
}
}
a.push_back({now,n});
for(int i=0;i<a.size();i++){
cout<<a[i].first<<" "<<a[i].second<<endl;
}
return 0;
}
对拍
#include<bits/stdc++.h>
#include<windows.h>
using namespace std;
int main(){
int t=10;
clock_t startTime,endTime;
while(t--){
system("data.exe > data.txt");
system("test.exe < data.txt > test.txt");
startTime = clock();
system("std.exe < data.txt > std.txt");
endTime = clock();
if(system("fc std.txt test.txt")){
cout<<"Wrong Answer"<<endl;
break;
}
else{
cout<<"Accepted"<<endl;
}
cout<<"The run time is: "<<(double)(endTime-startTime)/CLOCKS_PER_SEC<<"s"<< endl;
}
if(t==0) cout<<"no error"<<endl;
else cout<<"error"<<endl;
return 0;
}
模拟栈
模拟栈
#include<bits/stdc++.h>
#define int long long
using namespace std;
const int maxn=1e6+10;
int top=0;
int s[maxn];
int t,n;
string s1;
signed main(){
cin>>t;
int x;
while(t--){
top=0;
cin>>n;
for(int i=1;i<=n;i++){
cin>>s1;
if(s1=="push"){
cin>>x;
top++;
s[top]=x;
}
else if(s1=="pop"){
if(top==0){
cout<<"Empty"<<endl;
}
else{
top--;
}
}
else if(s1=="size"){
cout<<top<<endl;
}
else if(s1=="query"){
if(top!=0){
cout<<s[top]<<endl;
}
else{
cout<<"Anguei!"<<endl;
}
}
}
}
return 0;
}
Floyd
Floyd
#include<bits/stdc++.h>
#define int long long
using namespace std;
int arr[110][110];
int n,m;
signed main(){
cin>>n>>m;
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++){
arr[i][j]=1e17;
if(i==j){
arr[i][j]=0;
}
}
}
for(int i=1;i<=m;i++){
int u,v,w;
cin>>u>>v>>w;
arr[u][v]=w;
arr[v][u]=w;
}
for(int k=1;k<=n;k++){
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++){
arr[i][j]=min(arr[i][j],arr[i][k]+arr[k][j]);
}
}
}
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++){
cout<<arr[i][j]<<" ";
}
cout<<endl;
}
return 0;
}
堆
小根堆
#include<bits/stdc++.h>
#define int long long
using namespace std;
const int maxn=1e6+10;
int heap[maxn],siz;
void push(int x){
int pos=siz++;
while(pos>0){
if(heap[(pos-1)/2]<=x){
break;
}
heap[pos]=heap[(pos-1)/2];
pos=(pos-1)/2;
}
heap[pos]=x;
return;
}
void pop(){
int pos=0;
int x=heap[--siz];
while(pos*2+1<siz){
int t=(heap[pos*2+1]<heap[pos*2+2])?pos*2+1:pos*2+2;
if(heap[t]>=x){
break;
}
heap[pos]=heap[t];
pos=t;
}
heap[pos]=x;
return;
}
int top(){
return heap[0];
}
int t,op;
signed main(){
cin>>t;
int x;
while(t--){
cin>>op;
if(op==1){
cin>>x;
push(x);
}
else if(op==2){
cout<<top()<<endl;
}
else if(op==3){
pop();
}
}
return 0;
}
模拟队列
模拟队列
#include<bits/stdc++.h>
#define int long long
using namespace std;
const int maxn=1e6+10;
int n,op;
int front=0;
int last=0;
int q[maxn];
signed main(){
cin>>n;
int x;
while(n--){
cin>>op;
if(op==1){
cin>>x;
last++;
q[last]=x;
}
if(op==2){
if(last-front==0){
cout<<"ERR_CANNOT_POP"<<endl;
}
else front++;
}
if(op==3){
if(last-front==0){
cout<<"ERR_CANNOT_QUERY"<<endl;
}
else cout<<q[front+1]<<endl;
}
if(op==4){
cout<<last-front<<endl;
}
}
}
快速幂
快速幂
#include<bits/stdc++.h>
using namespace std;
long long a,b,c;
long long qpow(long long x,long long y){
if(y==0)
return 1;
long long ans=1;
while(y!=0){
if(y&1){
ans=(ans%c*x%c)%c;
}
x=(x%c*x%c)%c;
y=y>>1;
}
ans=ans%c;
return ans;
}
int main(){
cin>>a>>b>>c;
long long ans=qpow(a,b);
ans=(ans+c)%c;
cout<<a<<"^"<<b<<" "<<"mod"<<" "<<c<<"="<<ans;
}
并查集
并查集
#include<bits/stdc++.h>
#define int long long
using namespace std;
const int maxn=1e6+10;
int f[maxn];
int getfa(int x){
if(f[x]==x)
return x;
else{
f[x]=getfa(f[x]);
return f[x];
}
}
int n,m;
signed main(){
cin>>n>>m;
for(int i=1;i<=n;i++){
f[i]=i;
}
for(int i=1;i<=m;i++){
int op,x,y;
cin>>op>>x>>y;
if(op==1){
f[getfa(x)]=getfa(y);
}
else{
if(getfa(x)==getfa(y)){
cout<<"Y"<<endl;
}
else{
cout<<"N"<<endl;
}
}
}
return 0;
}
筛法求素数
欧拉筛
#include<bits/stdc++.h>
#define int long long
using namespace std;
const int maxn=1e8+10;
bool flag[maxn];
int n,q,cnt;
int num[6000010];
signed main(){
std::ios::sync_with_stdio(0);
cin>>n>>q;
for(int i=2;i<=n;i++){
if(!flag[i]){
cnt++;
num[cnt]=i;
}
for(int j=1;j<=cnt&&i*num[j]<=n;j++){
flag[i*num[j]]=true;
if(i%num[j]==0){
break;
}
}
}
while(q--){
int x;
cin>>x;
cout<<num[x]<<endl;
}
return 0;
}
双端队列
list版本
#include<bits/stdc++.h>
#define int long long
using namespace std;
const int maxn=1e6+10;
list<int>arr[maxn];
int q;
string s1;
signed main(){
cin>>q;
while(q--){
cin>>s1;
if(s1=="push_back"){
int x,y;
cin>>x>>y;
arr[x].push_back(y);
}
else if(s1=="pop_back"){
int x;
cin>>x;
if(arr[x].size()==0)
continue;
arr[x].pop_back();
}
else if(s1=="push_front"){
int x,y;
cin>>x>>y;
arr[x].push_front(y);
}
else if(s1=="pop_front"){
int x;
cin>>x;
if(arr[x].size()==0)
continue;
arr[x].pop_front();
}
else if(s1=="size"){
int x;
cin>>x;
cout<<arr[x].size()<<endl;
}
else if(s1=="front"){
int x;
cin>>x;
if(arr[x].size()==0)
continue;
cout<<arr[x].front()<<endl;
}
else if(s1=="back"){
int x;
cin>>x;
if(arr[x].size()==0)
continue;
cout<<arr[x].back()<<endl;
}
}
return 0;
}
哈希
单哈希
#include<bits/stdc++.h>
#define ull unsigned long long
#define int long long
using namespace std;
const int base=13131,maxn=1e6+10;
ull site[maxn];
map<int,int>mp;
int n,ans=0;
signed main(){
cin>>n;
site[0]=1;
for(int i=1;i<=maxn;i++){
site[i]=site[i-1]*base;
}
string s1;
for(int i=1;i<=n;i++){
cin>>s1;
ull turn=0;
for(int i=0;i<s1.size();i++){
int num=(s1[i]-'a'+1);
turn+=site[i+1]*num;
}
if(!mp[turn]){
ans++;
mp[turn]++;
}
}
cout<<ans;
return 0;
}
双哈希
#include<bits/stdc++.h>
#define ull unsigned long long
#define int long long
using namespace std;
const int base1=13131,base2=13331,maxn=1e6+10;
ull site1[maxn],site2[maxn];
map<pair<int,int>,int>mp;
int n,ans=0;
signed main(){
cin>>n;
site1[0]=1;
site2[0]=1;
for(int i=1;i<=maxn;i++){
site1[i]=site1[i-1]*base1;
site2[i]=site2[i-1]*base2;
}
string s1;
for(int i=1;i<=n;i++){
cin>>s1;
ull turn1=0,turn2=0;
for(int i=0;i<s1.size();i++){
int num=(s1[i]-'a'+1);
turn1+=site1[i+1]*num;
turn2+=site2[i+1]*num;
}
if(!mp[make_pair(turn1,turn2)]){
ans++;
mp[make_pair(turn1,turn2)]++;
}
}
cout<<ans;
return 0;
}
异或哈希
#include<bits/stdc++.h>
#define ull unsigned long long
#define int long long
using namespace std;
const int maxn=1e6+10;
ull site[maxn];
map<int,int>mp;
int n,ans=0;
signed main(){
cin>>n;
site[0]=1;
std::mt19937_64 rnd(time(0));
for(int i=1;i<=maxn;i++){
site[i] = rnd();
}
string s1;
for(int i=1;i<=n;i++){
cin>>s1;
ull turn=0;
for(int i=0;i<s1.size();i++){
int num=(s1[i]-'a'+1);
turn^=site[i+1]*num;
}
if(!mp[turn]){
ans++;
mp[turn]++;
}
}
cout<<ans;
return 0;
}
树的直径和直径中点
dfs版本
#include<bits/stdc++.h>
#define int long long
using namespace std;
const int maxn=1e5+10;
int n,q;
struct edge{
int next,to;
}e[maxn<<1];
int head[maxn],cnt;
void add(int x,int y){
e[++cnt].next=head[x];
e[cnt].to=y;
head[x]=cnt;
}
int dep[maxn],maxx=0,maxi=0;
int father[maxn],node;
void dfs(int x,int fa){
dep[x]=dep[fa]+1;
father[x]=fa;
if(dep[x]>maxx){
maxx=dep[x];
maxi=x;
}
for(int i=head[x];i;i=e[i].next){
int v=e[i].to;
if(v==fa)
continue;
dfs(v,x);
}
}
void getmid(int x,int mid){
if(dep[x]==mid){
node=x;
return;
}
else{
getmid(father[x],mid);
}
}
signed main(){
freopen("tree.in","r",stdin);
freopen("tree.out","w",stdout);
cin>>n>>q;
for(int i=1;i<n;i++){
int x,y;
cin>>x>>y;
add(x,y);
add(y,x);
}
dfs(1,0);
dfs(maxi,0);
if(maxx%2!=0)
getmid(maxi,maxx/2+1);
else node=0;
return 0;
}
最小生成树
Kruskal
#include<bits/stdc++.h>
using namespace std;
const int maxn=1000100;
int n,m,sma=0,tot=0;
int fa[maxn];
bool flag=true;
struct edge{
int from;
int to;
int w;
}e[maxn];
inline bool cmp(edge x,edge y){
return x.w<y.w;
}
int getfa(int x){
if(fa[x]==x)
return x;
else
return fa[x]=getfa(fa[x]);
}
void solve(){
tot=0;
sort(e+1,e+m+1,cmp);
for(int i=1;i<=n;i++){
fa[i]=i;
}
for(int i=1;i<=m;i++){
int x=e[i].from,y=e[i].to;
if(getfa(x)!=getfa(y)){
fa[getfa(x)]=getfa(y);
sma+=e[i].w;
tot++;
if(tot==n-1)
break;
}
}
if(tot!=n-1){
cout<<"NO"<<endl;
flag=false;
}
}
int main(){
flag=true;
cin>>n>>m;
for(int i=1;i<=m;i++){
cin>>e[i].from>>e[i].to>>e[i].w;
}
solve();
if(false){
return 0;
}
else{
cout<<sma<<endl;
}
return 0;
}
Prim
#include<bits/stdc++.h>
#define int long long
using namespace std;
const int maxn=1e6+10;
int n,m;
struct edge{
int next,to,val;
}e[maxn<<1];
int head[maxn],cnt;
struct s{
int u,d;
};
bool operator<(const s &x,const s &y){
return x.d>y.d;
}
priority_queue<s> q;
int dis[maxn];
bool vis[maxn];
int res=0,tot=0;
void prim(){
memset(dis,0x3f,sizeof(dis));
dis[1]=0;
q.push({1,0});
while(!q.empty()){
if(tot>=n)
break;
int u=q.top().u;
int d=q.top().d;
q.pop();
if(vis[u]){
continue;
}
vis[u]=true;
++tot;
res+=d;
for(int i=head[u];i;i=e[i].next){
int v=e[i].to;
int w=e[i].val;
if(w<dis[v]){
dis[v]=w;
q.push({v,w});
}
}
}
}
void add(int x,int y,int w){
e[++cnt].next=head[x];
e[cnt].to=y;
e[cnt].val=w;
head[x]=cnt;
}
signed main(){
cin>>n>>m;
for(int i=1;i<=m;i++){
int x,y,z;
cin>>x>>y>>z;
add(x,y,z);
add(y,x,z);
}
prim();
if(tot==n){
cout<<res;
}
else{
cout<<"No";
}
}
拓扑排序
拓扑排序
#include<bits/stdc++.h>
using namespace std;
bool g[110][110];
int in[110];
int n;
queue<int> q;
void toposort(){
for(int i=1;i<=n;i++){
if(in[i]==0)
q.push(i);
}
while(!q.empty()){
int x=q.front();
cout<<x<<" ";
q.pop();
for(int i=1;i<=n;i++){
if(g[x][i]){
in[i]--;
if(in[i]==0)
q.push(i);
}
}
}
}
int main(){
memset(g,false,sizeof(g));
memset(in,0,sizeof(in));
cin>>n;
int e;
for(int i=1;i<=n;i++){
while(cin>>e){
if(e!=0){
g[i][e]=true;
in[e]++;
continue;
}
else break;
}
}
toposort();
return 0;
}
KMP
KMP
#include<bits/stdc++.h>
#define int long long
using namespace std;
const int maxn=1e6+10;
char s1[maxn],s2[maxn];
int len1,len2;
int kmp[maxn];
signed main(){
cin>>s1+1;
cin>>s2+1;
len1=strlen(s1+1);
len2=strlen(s2+1);
int j=0;
for(int i=2;i<=len2;i++){
while(j&&s2[i]!=s2[j+1]){
j=kmp[j];
}
if(s2[j+1]==s2[i]){
j++;
}
kmp[i]=j;
}
j=0;
for(int i=1;i<=len1;i++){
while(j>0&&s2[j+1]!=s1[i]){
j=kmp[j];
}
if(s2[j+1]==s1[i]){
j++;
}
if(j==len2){
cout<<i-len2+1<<endl;
j=kmp[j];
}
}
for(int i=1;i<=len2;i++){
cout<<kmp[i]<<" ";
}
return 0;
}
判断负环(spfa)
spfa
#include<bits/stdc++.h>
#define int long long
using namespace std;
const int maxn=6e3+10;
struct edge{
int next,to,val;
}e[maxn];
int head[maxn],cnt;
queue<int>q;
int dis[maxn],num[maxn];
bool vis[maxn];
int t,n,m;
void add(int x,int y,int w){
e[++cnt].next=head[x];
e[cnt].to=y;
e[cnt].val=w;
head[x]=cnt;
}
bool spfa(){
memset(dis,0x3f,sizeof(dis));
memset(vis,0,sizeof(vis));
memset(num,0,sizeof(num));
dis[1]=0;
vis[1]=true;
q.push(1);
while(!q.empty()){
int f=q.front();
q.pop();
vis[f]=false;
for(int i=head[f];i;i=e[i].next){
int v=e[i].to;
int w=e[i].val;
if(dis[v]>dis[f]+w){
dis[v]=dis[f]+w;
num[v]=num[f]+1;
if(num[v]>=n)
return true;
if(!vis[v]){
q.push(v);
vis[v]=true;
}
}
}
}
return false;
}
signed main(){
cin>>t;
while(t--){
for(int i=0;i<maxn;i++){
e[i].next=0;
head[i]=0;
}
cnt=0;
cin>>n>>m;
for(int i=1;i<=m;i++){
int u,v,w;
cin>>u>>v>>w;
add(u,v,w);
if(w>=0)
add(v,u,w);
}
if(spfa()){
cout<<"YES"<<endl;
}
else{
cout<<"NO"<<endl;
}
}
return 0;
}
单调栈
单调栈
#include<bits/stdc++.h>
using namespace std;
const int maxn=3e6+10;
int arr[maxn],ans[maxn];
stack<int> s;
int n;
int main(){
cin>>n;
for(int i=1;i<=n;i++){
cin>>arr[i];
while(!s.empty()&&arr[i]>arr[s.top()]){
ans[s.top()]=i;
s.pop();
}
s.push(i);
}
for(int i=1;i<=n;i++){
cout<<ans[i]<<" ";
}
}
线段树
单点修改 区间查询
#include<bits/stdc++.h>
#define lid (id<<1)
#define rid ((id<<1)+1)
using namespace std;
const int maxn=3e6+10;
struct tree{
int sum;
int maxx;
int lazy;
}tr[maxn];
int arr[maxn];
int n,q;
void build(int id,int l,int r){
if(l==r){
tr[id].maxx=arr[l];
tr[id].sum=arr[l];
}
int mid=(l+r)/2;
build(lid,l,mid);
build(rid,mid+1,r);
tr[id].maxx=max(tr[lid].maxx,tr[rid].maxx);
tr[id].sum=tr[lid].sum+tr[rid].sum;
}
int query_sum(int id,int l,int r,int x,int y){
if(x<=l&&r<=y){
return tr[id].sum;
}
int mid=(l+r)/2,ans=0;
if(x<=mid){
ans+=query_sum(lid,l,mid,x,y);
}
if(y>mid){
ans+=query_sum(rid,mid+1,r,x,y);
}
return ans;
}
int query_max(int id,int l,int r,int x,int y){
if(x<=l&&r<=y){
return tr[id].maxx;
}
int mid=(l+r)/2,ans=0;
if(x<=mid){
ans=max(ans,query_sum(lid,l,mid,x,y));
}
if(y>mid){
ans=max(ans,query_sum(rid,mid+1,r,x,y));
}
return ans;
}
void change(int id,int l,int r,int x,int v){
if(l==r){
tr[id].maxx=v;
tr[id].sum=v;
return;
}
int mid=(l+r)/2;
if(x<=mid)change(lid,l,mid,x,v);
else change(rid,mid+1,r,x,v);
tr[id].maxx=max(tr[lid].maxx,tr[rid].maxx);
tr[id].sum=tr[lid].sum+tr[rid].sum;
}
int main(){
cin>>n>>q;
for(int i=1;i<=n;i++){
cin>>arr[i];
}
build(1,1,n);
int flag;
while(q--){
cin>>flag;
if(flag==1){
int x,y;
cin>>x>>y;
change(1,1,n,x,y);
}
else{
int x,y;
cin>>x>>y;
cout<<query_max(1,1,n,x,y)<<" "<<query_sum(1,1,n,x,y);
}
}
}
区间修改 区间查询
#include<bits/stdc++.h>
#define int long long
#define lid (id*2)
#define rid ((id*2)+1)
using namespace std;
const int maxn=1e5+10;
struct tree{
int sum;
int lazy;
}tr[maxn<<2];
int arr[maxn];
int n,q;
void push_up(int id){
tr[id].sum=tr[lid].sum+tr[rid].sum;
}
void push_down(int id,int l,int r){
if(tr[id].lazy){
int mid=(l+r)/2;
tr[lid].lazy+=tr[id].lazy;
tr[rid].lazy+=tr[id].lazy;
tr[lid].sum+=tr[id].lazy*(mid-l+1);
tr[rid].sum+=tr[id].lazy*(r-mid);
tr[id].lazy=0;
}
}
void update(int id,int l,int r,int x,int y,int v){
if(l>=x&&r<=y){
tr[id].lazy+=v;
tr[id].sum+=v*(r-l+1);
return;
}
push_down(id,l,r);
int mid=(l+r)/2;
if(x<=mid){
update(lid,l,mid,x,y,v);
}
if(y>mid){
update(rid,mid+1,r,x,y,v);
}
push_up(id);
}
int query(int id,int l,int r,int x,int y){
if(l>=x&&r<=y){
return tr[id].sum;
}
push_down(id,l,r);
int mid=(l+r)/2,ans=0;
if(x<=mid) ans+=query(lid,l,mid,x,y);
if(y>mid) ans+=query(rid,mid+1,r,x,y);
return ans;
}
void build(int id,int l,int r){
if(l==r){
tr[id].sum=arr[l];
return;
}
int mid=(l+r)/2;
build(lid,l,mid);
build(rid,mid+1,r);
tr[id].sum=tr[lid].sum+tr[rid].sum;
}
signed main(){
cin>>n>>q;
for(int i=1;i<=n;i++){
cin>>arr[i];
}
build(1,1,n);
int flag;
while(q--){
cin>>flag;
if(flag==1){
int x,y,z;
cin>>x>>y>>z;
update(1,1,n,x,y,z);
}
else{
int x,y;
cin>>x>>y;
cout<<query(1,1,n,x,y)<<endl;
}
}
return 0;
}
区间修改 区间查询pro
#include<bits/stdc++.h>
#define int long long
#define lid (id<<1)
#define rid ((id<<1)+1)
using namespace std;
const int maxn=1e5+10;
int n,m,mod;
int arr[maxn];
struct tree{
int sum,mul,add;
}tr[maxn<<2];
void push_up(int id){
tr[id].sum=(tr[lid].sum+tr[rid].sum)%mod;
}
void build(int id,int l,int r){
tr[id].mul=1;
tr[id].add=0;
if(l==r){
tr[id].sum=arr[l];
tr[id].sum%=mod;
return;
}
int mid=(l+r)/2;
build(lid,l,mid);
build(rid,mid+1,r);
push_up(id);
tr[id].sum%=mod;
return;
}
void push_down(int id,int l,int r){
int mid=(l+r)/2;
tr[lid].sum=(tr[lid].sum*tr[id].mul+(mid-l+1)*tr[id].add)%mod;
tr[rid].sum=(tr[rid].sum*tr[id].mul+(r-mid)*tr[id].add)%mod;
tr[lid].mul=(tr[lid].mul*tr[id].mul)%mod;
tr[rid].mul=(tr[rid].mul*tr[id].mul)%mod;
tr[lid].add=(tr[lid].add*tr[id].mul+tr[id].add)%mod;
tr[rid].add=(tr[rid].add*tr[id].mul+tr[id].add)%mod;
tr[id].add=0;
tr[id].mul=1;
return;
}
void update1(int id,int l,int r,int x,int y,int v){
if(x<=l&&y>=r){
tr[id].sum=(tr[id].sum*v)%mod;
tr[id].mul=(tr[id].mul*v)%mod;
tr[id].add=(tr[id].add*v)%mod;
return;
}
push_down(id,l,r);
int mid=(l+r)/2;
if(x<=mid){
update1(lid,l,mid,x,y,v);
}
if(y>mid){
update1(rid,mid+1,r,x,y,v);
}
push_up(id);
return;
}
void update2(int id,int l,int r,int x,int y,int v){
if(x<=l&&y>=r){
tr[id].sum=(tr[id].sum+v*(r-l+1))%mod;
tr[id].add=(tr[id].add+v)%mod;
return;
}
push_down(id,l,r);
int mid=(l+r)/2;
if(x<=mid){
update2(lid,l,mid,x,y,v);
}
if(y>mid){
update2(rid,mid+1,r,x,y,v);
}
push_up(id);
return;
}
int query(int id,int l,int r,int x,int y){
if(y<l||r<x){
return 0;
}
if(x<=l&&y>=r){
return tr[id].sum;
}
push_down(id,l,r);
int mid=(l+r)/2;
return (query(lid,l,mid,x,y)+query(rid,mid+1,r,x,y))%mod;
}
signed main(){
cin>>n>>m>>mod;
for(int i=1;i<=n;i++){
cin>>arr[i];
}
build(1,1,n);
int flag,x,y,z;
while(m--){
cin>>flag;
if(flag==1){
cin>>x>>y>>z;
update1(1,1,n,x,y,z);
}
else if(flag==2){
cin>>x>>y>>z;
update2(1,1,n,x,y,z);
}
else{
cin>>x>>y;
cout<<query(1,1,n,x,y)<<'\n';
}
}
}
传递闭包
传递闭包
#include<bits/stdc++.h>
using namespace std;
int n;
bitset<110>a[110];
int main(){
cin>>n;
int x;
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++){
cin>>x;
if(x)
a[i][j]=true;
else
a[i][j]=false;
}
}
for(int j=1;j<=n;j++){
for(int i=1;i<=n;i++){
if(a[i][j]){
a[i]|=a[j];
}
}
}
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++){
if(a[i][j]){
cout<<1<<" ";
}
else{
cout<<0<<" ";
}
}
cout<<'\n';
}
}
裴蜀定理
裴蜀定理
#include<bits/stdc++.h>
using namespace std;
const int maxn=25;
int n;
int arr[maxn];
int gcd(int x,int y){
return y?gcd(y,x%y):x;
}
int main(){
cin>>n;
for(int i=1;i<=n;i++){
cin>>arr[i];
if(arr[i]<0){
arr[i]=-arr[i];
}
}
for(int i=1;i<n;i++){
arr[i+1]=gcd(arr[i+1],arr[i]);
}
cout<<arr[n];
}
树状数组
单点修改 区间查询
#include<bits/stdc++.h>
using namespace std;
const int maxn=5e5+10;
int c[maxn],arr[maxn];
int n,m;
int lowbit(int x){
return x&-x;
}
void update(int x,int val){
while(x<=n){
c[x]+=val;
x+=lowbit(x);
}
}
int query(int x){
int ans=0;
while(x>0){
ans+=c[x];
x-=lowbit(x);
}
return ans;
}
int check(int l,int r){
return query(r)-query(l-1);
}
int main(){
cin>>n>>m;
for(int i=1;i<=n;i++){
cin>>arr[i];
update(i,arr[i]);
}
for(int i=1;i<=m;i++){
int flag,x,y;
cin>>flag>>x>>y;
if(flag==1){
update(x,y);
}
else{
cout<<check(x,y)<<endl;
}
}
return 0;
}
区间修改 单点查询
#include<bits/stdc++.h>
using namespace std;
const int maxn=5e5+10;
int c[maxn],arr[maxn];
int n,m;
int lowbit(int x){
return x&-x;
}
void insert(int x,int val){
while(x<=n){
c[x]+=val;
x+=lowbit(x);
}
}
void update(int x,int y,int val){
insert(x,val);
insert(y+1,-val);
}
int query(int x){
int ans=0;
while(x>0){
ans+=c[x];
x-=lowbit(x);
}
return ans;
}
int main(){
cin>>n>>m;
for(int i=1;i<=n;i++){
cin>>arr[i];
update(i,i,arr[i]);
}
for(int i=1;i<=m;i++){
int flag,x,y,z;
cin>>flag>>x;
if(flag==1){
cin>>y>>z;
update(x,y,z);
}
else{
cout<<query(x)<<endl;
}
}
return 0;
}
矩阵快速幂
矩阵快速幂
#include<bits/stdc++.h>
#define int long long
using namespace std;
const int mod=1e9+7;
struct matrix{
int c[110][110];
}arr,base;
int n,k;
matrix operator*(const matrix &x,const matrix &y){
matrix a;
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++){
a.c[i][j]=0;
}
}
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++){
for(int k=1;k<=n;k++){
a.c[i][j]+=x.c[i][k]*y.c[k][j]%mod;
a.c[i][j]%=mod;
}
}
}
return a;
}
void qpow(matrix &a,int &b){
while(b>0){
if(b%2==1){
base=base*a;
}
a=a*a;
b=b>>1;
}
}
signed main(){
cin>>n>>k;
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++){
cin>>arr.c[i][j];
}
}
for(int i=1;i<=n;i++){
base.c[i][i]=1;
}
qpow(arr,k);
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++){
cout<<base.c[i][j]<<" ";
}
cout<<endl;
}
}
LCA
倍增
#include<bits/stdc++.h>
using namespace std;
const int maxn=5e5+10;
int n,m,s;
struct edge{
int next,to;
}e[maxn<<1];
int head[maxn],cnt;
int dep[maxn],fa[maxn][22];
void add(int x,int y){
e[++cnt].next=head[x];
e[cnt].to=y;
head[x]=cnt;
}
void dfs(int u,int f){
dep[u]=dep[f]+1;
fa[u][0]=f;
for(int i=1;(1<<i)<=dep[u];i++){
fa[u][i]=fa[fa[u][i-1]][i-1];
}
for(int i=head[u];i;i=e[i].next){
int v=e[i].to;
if(v==f)
continue;
dfs(v,u);
}
}
int lca(int a,int b){
if(dep[a]>dep[b]){
swap(a,b);
}
for(int i=20;i>=0;i--){
if(dep[a]<=dep[b]-(1<<i)){
b=fa[b][i];
}
}
if(a==b)return a;
for(int i=20;i>=0;i--){
if(fa[a][i]==fa[b][i]){
continue;
}
else{
a=fa[a][i],b=fa[b][i];
}
}
return fa[a][0];
}
int main(){
cin>>n>>m>>s;
int u,v;
for(int i=1;i<n;i++){
cin>>u>>v;
add(u,v);
add(v,u);
}
dfs(s,0);
for(int i=1;i<=m;i++){
cin>>u>>v;
cout<<(lca(u,v))<<endl;
}
return 0;
}
dfs序
#include<bits/stdc++.h>
using namespace std;
const int maxn=5e5+10;
int n,m,s;
struct edge{
int next,to;
}e[maxn<<1];
int head[maxn],cnt;
int dfn[maxn],mi[19][maxn],dn;
void add(int x,int y){
e[++cnt].next=head[x];
e[cnt].to=y;
head[x]=cnt;
}
int get(int x,int y){
return dfn[x]<dfn[y]?x:y;
}
void dfs(int u,int f){
mi[0][dfn[u]=++dn]=f;
for(int i=head[u];i;i=e[i].next){
int v=e[i].to;
if(v==f)
continue;
dfs(v,u);
}
}
int lca(int a,int b){
if(a==b)return a;
if((a=dfn[a])>(b=dfn[b])){
swap(a,b);
}
int d=__lg(b-a++);
return get(mi[d][a],mi[d][b-(1<<d)+1]);
}
int main(){
cin>>n>>m>>s;
int u,v;
for(int i=1;i<n;i++){
cin>>u>>v;
add(u,v);
add(v,u);
}
dfs(s,0);
for(int i=1;i<=__lg(n);i++){
for(int j=1;j+(1<<i)-1<=n;j++){
mi[i][j]=get(mi[i-1][j],mi[i-1][j+(1<<i-1)]);
}
}
for(int i=1;i<=m;i++){
cin>>u>>v;
cout<<(lca(u,v))<<endl;
}
return 0;
}
树链剖分
#include<bits/stdc++.h>
using namespace std;
const int maxn=5e5+10;
int n,m,s;
struct edge{
int next,to;
}e[maxn<<1];
int head[maxn],cnt;
int dep[maxn],siz[maxn],son[maxn],top[maxn],fa[maxn];
void add(int x,int y){
e[++cnt].next=head[x];
e[cnt].to=y;
head[x]=cnt;
}
void dfs1(int u,int f){
siz[u]=1;
dep[u]=dep[f]+1;
fa[u]=f;
for(int i=head[u];i;i=e[i].next){
int v=e[i].to;
if(v==f)
continue;
dfs1(v,u);
siz[u]+=siz[v];
if(!son[u]||siz[son[u]]<siz[v]){
son[u]=v;
}
}
}
void dfs2(int u,int t){
top[u]=t;
if(son[u]){
dfs2(son[u],t);
}
for(int i=head[u];i;i=e[i].next){
int v=e[i].to;
if(v==fa[u]||v==son[u])
continue;
dfs2(v,v);
}
}
int lca(int u,int v){
while(top[u]!=top[v]){
if(dep[top[u]]>=dep[top[v]]){
u=fa[top[u]];
}
else{
v=fa[top[v]];
}
}
return dep[u]<dep[v]?u:v;
}
int main(){
cin>>n>>m>>s;
int u,v;
for(int i=1;i<n;i++){
cin>>u>>v;
add(u,v);
add(v,u);
}
dfs1(s,0);
dfs2(s,s);
for(int i=1;i<=m;i++){
cin>>u>>v;
cout<<lca(u,v)<<endl;
}
return 0;
}
Dijkstra
堆优化Dijkstra
#include<bits/stdc++.h>
#define int long long
using namespace std;
const int INF=2147483647;
const int maxn=5e5+10;
int n,m,s;
int dis[maxn];
struct edge{
int next,to,val;
}e[maxn<<1];
struct node{
int s,w;
bool operator<(const node &t)const{
return t.w<w;
}
};
int head[maxn],cnt;
void add(int u,int v,int w){
e[++cnt].next=head[u];
e[cnt].to=v;
e[cnt].val=w;
head[u]=cnt;
}
void dijkstra(int x){
priority_queue<node> q;
dis[x]=0;
q.push({x,0});
while(!q.empty()){
node t=q.top();
q.pop();
if(dis[t.s]<t.w)
continue;
for(int i=head[t.s];i;i=e[i].next){
int v=e[i].to;
if(dis[v]>e[i].val+t.w){
dis[v]=e[i].val+t.w;
q.push({v,dis[v]});
}
}
}
}
signed main(){
cin>>n>>m>>s;
int u,v,w;
for(int i=1;i<=m;i++){
cin>>u>>v>>w;
add(u,v,w);
}
for(int i=1;i<=n;i++){
dis[i]=INF;
}
dijkstra(s);
for(int i=1;i<=n;i++){
cout<<dis[i]<<" ";
}
}
tarian缩点
缩点
#include<bits/stdc++.h>
using namespace std;
const int maxn=1e4+10;
int n,m,cnt,tim,top,s;
int p[maxn],head[maxn],sd[maxn],dfn[maxn],low[maxn];
int stac[maxn];
bool vis[maxn];
int h[maxn],in[maxn],dist[maxn];
struct Edge{
int to,next,from;
}edge[maxn*10],ed[maxn*10];
void add(int x,int y){
edge[++cnt].next=head[x];
edge[cnt].from=x;
edge[cnt].to=y;
head[x]=cnt;
}
void tarjan(int x){
low[x]=dfn[x]=++tim;
stac[++top]=x;
vis[x]=true;
for(int i=head[x];i;i=edge[i].next){
int v=edge[i].to;
if(!dfn[v]){
tarjan(v);
low[x]=min(low[x],low[v]);
}
else if(vis[v]){
low[x]=min(low[x],low[v]);
}
}
if(dfn[x]==low[x]){
int y;
while(y=stac[top--]){
sd[y]=x;
vis[y]=false;
if(x==y)break;
p[x]+=p[y];
}
}
}
int topo(){
queue<int>q;
int tot=0;
for(int i=1;i<=n;i++){
if(sd[i]==i&&!in[i]){
q.push(i);
dist[i]=p[i];
}
}
while(!q.empty()){
int k=q.front();
q.pop();
for(int i=h[k];i;i=ed[i].next){
int v=ed[i].to;
dist[v]=max(dist[v],dist[k]+p[v]);
in[v]--;
if(in[v]==0){
q.push(v);
}
}
}
int ans=0;
for(int i=1;i<=n;i++){
ans=max(ans,dist[i]);
}
return ans;
}
signed main(){
cin>>n>>m;
for(int i=1;i<=n;i++){
cin>>p[i];
}
for(int i=1;i<=m;i++){
int u,v;
cin>>u>>v;
add(u,v);
}
for(int i=1;i<=n;i++){
if(!dfn[i]){
tarjan(i);
}
}
for(int i=1;i<=m;i++){
int x=sd[edge[i].from];
int y=sd[edge[i].to];
if(x!=y){
ed[++s].next=h[x];
ed[s].to=y;
ed[s].from=x;
h[x]=s;
in[y]++;
}
}
cout<<topo();
return 0;
}
## nim游戏
<details>
<summary>nim游戏</summary>
```cpp
#include<bits/stdc++.h>
using namespace std;
int main(){
int t;
cin>>t;
while(t--){
int n;
cin>>n;
int ans=0;
for(int i=1;i<=n;i++){
int a;
cin>>a;
ans^=a;
}
if(ans==0){
cout<<"No"<<endl;
}
else cout<<"Yes"<<endl;
}
return 0;
}
欧拉路径
欧拉路径
#include<bits/stdc++.h>
using namespace std;
const int maxn=1e5+10;
int n,m,del[maxn],cnt[2],beg=1;
int line[maxn][2];
stack<int>s;
vector<int>e[maxn];
void dfs(int now){
for(int i=del[now];i<e[now].size();i=del[now]){
del[now]=i+1;
dfs(e[now][i]);
}
s.push(now);
}
int main(){
cin>>n>>m;
int u,v;
for(int i=1;i<=m;i++){
cin>>u>>v;
e[u].push_back(v);
line[u][1]++;
line[v][0]++;
}
for(int i=1;i<=n;i++){
sort(e[i].begin(),e[i].end());
}
bool flag=true;
for(int i=1;i<=n;i++){
if(line[i][1]!=line[i][0]){
flag=false;
if(line[i][1]-line[i][0]==1){
cnt[1]++;
beg=i;
}
else if(line[i][0]-line[i][1]==1){
cnt[0]++;
}
else{
cout<<"No";
return 0;
}
}
}
if((!flag)&&!(cnt[0]==cnt[1]&&cnt[0]==1)){
cout<<"No";
return 0;
}
dfs(beg);
while(!s.empty()){
cout<<s.top()<<" ";
s.pop();
}
return 0;
}
康托展开
康托展开
#include<bits/stdc++.h>
#define int long long
using namespace std;
const int maxn=1e6+10;
const int mod=998244353;
int n;
int arr[maxn],c[maxn],lowbit[maxn];
int fac[maxn],ans;
void add(int x,int k){
while(x<=n){
c[x]+=k;
x+=lowbit[x];
}
}
int sum(int x){
int t=0;
while(x>0){
t+=c[x];
x-=lowbit[x];
}
return t;
}
signed main(){
cin>>n;
fac[0]=1;
for(int i=1;i<n;i++){
fac[i]=fac[i-1]*i%mod;
lowbit[i]=i&-i;
}
lowbit[n]=n&-n;
for(int i=1;i<=n;i++){
add(i,1);
}
for(int i=1;i<=n;i++){
cin>>arr[i];
ans=(ans+((sum(arr[i])-1)*fac[n-i])%mod)%mod;
add(arr[i],-1);
}
cout<<ans+1;
return 0;
}
差分约束
差分约束
#include<bits/stdc++.h>
#define int long long
using namespace std;
const int INF=2e9;
const int maxn=3e5+10;
int n,m;
int dis[maxn],num[maxn];
bool vis[maxn];
struct edge{
int next,to,val;
}e[maxn];
int head[maxn],cnt;
queue<int>q;
void add(int u,int v,int w){
e[++cnt].next=head[u];
e[cnt].to=v;
e[cnt].val=w;
head[u]=cnt;
}
bool spfa(int x){
dis[x]=0;
q.push(x);
vis[x]=true;
num[x]++;
while(!q.empty()){
int turn=q.front();
q.pop();
vis[turn]=false;
for(int i=head[turn];i;i=e[i].next){
int v=e[i].to;
if(dis[v]>dis[turn]+e[i].val){
dis[v]=dis[turn]+e[i].val;
if(!vis[v]){
q.push(v);
vis[v]=true;
num[v]++;
if(num[v]==n+1){
return false;
}
}
}
}
}
return true;
}
signed main(){
cin>>n>>m;
for(int i=1;i<=n;i++){
dis[i]=INF;
}
int u,v,w;
for(int i=1;i<=m;i++){
cin>>u>>v>>w;
add(v,u,w);
}
for(int i=1;i<=n;i++){
add(n+1,i,0);
}
if(!spfa(n+1)){
cout<<"NO";
return 0;
}
for(int i=1;i<=n;i++){
cout<<dis[i]<<" ";
}
return 0;
}
有理数取余
有理数取余
#include<bits/stdc++.h>
#define int long long
using namespace std;
const int mod=19260817;
int a,b,x,y;
inline int read(){
int res=0,ch=getchar();
while(!isdigit(ch)&&ch!=EOF)
ch=getchar();
while(isdigit(ch)){
res=(res<<3)+(res<<1)+(ch-'0');
res%=mod;
ch=getchar();
}
return res;
}
void exgcd(int a,int b){
if(b==0){
x=1;
y=0;
return;
}
exgcd(b,a%b);
int turn=x;
x=y;
y=turn-a/b*y;
}
signed main(){
a=read();
b=read();
if(b==0){
cout<<"Angry!";
return 0;
}
exgcd(b,mod);
x=(x%mod+mod)%mod;
cout<<a*x%mod;
}
最长公共子序列
最长公共子序列
#include<bits/stdc++.h>
#define int long long
using namespace std;
const int maxn=1e5+10;
int n;
int a[maxn],b[maxn],site[maxn],dp[maxn];
signed main(){
cin>>n;
for(int i=1;i<=n;i++){
cin>>a[i];
site[a[i]]=i;
}
for(int i=1;i<=n;i++){
cin>>b[i];
dp[i]=0x7fffffff;
}
int len=0;
for(int i=1;i<=n;i++){
int l=0,r=len,mid;
if(site[b[i]]>dp[len]){
dp[++len]=site[b[i]];
}
else{
while(l<r){
mid=(l+r)/2;
if(dp[mid]>site[b[i]]){
r=mid;
}
else{
l=mid+1;
}
}
dp[l]=min(dp[l],site[b[i]]);
}
}
cout<<len;
return 0;
}
manacher
manacher
#include<bits/stdc++.h>
using namespace std;
const int maxn=51000100;
char a[maxn],s[maxn];
int num[maxn];
int len,ans;
void turn(){
s[0]=s[1]='#';
for(int i=0;i<len;i++){
s[i*2+2]=a[i];
s[i*2+3]='#';
}
len=len*2+2;
s[len]=0;
}
void manacher(){
int maxr=0,mid;
for(int i=1;i<len;i++){
if(i<maxr){
num[i]=min(num[(mid<<1)-i],num[mid]+mid-i);
}
else{
num[i]=1;
}
for(;s[i+num[i]]==s[i-num[i]];++num[i]);
if(num[i]+i>maxr){
maxr=num[i]+i;
mid=i;
}
}
}
int main(){
cin>>a;
len=strlen(a);
turn();
manacher();
for(int i=0;i<len;i++){
ans=max(ans,num[i]);
}
cout<<ans-1;
return 0;
}