快CSP了,放一下自己打的板子。

/*tarjan 缩点*/
void tarajn(int x)
{
	dfn[x]=low[x]=++cnt;zhan[++top]=x;
	vis[x]=1;
	for(int i=head[x];i;i=e[i].nt)
	{
		if(!dfn[e[i].to])
		{
			tarjan(e[i].to);
			low[x]=min(low[x],low[e[i].to]);
		}
		else if(vis[e[i].to])low[x]=min(low[x],dfn[e[i].to]);
	}
	if(dfn[x]==low[x])
	{
		int k;kuai++;
		do
		{
			k=zhan[top--];
			c[k]=kuai;
			vis[k]=0;
		}while(x!=k);
	}
}
/*快速幂*/
LL ksm(LL a,LL b,LL mod)
{
	LL res=1;
	for(;b;b>>=1,a=a*a%mod)if(b&1)res=res*a%mod;
	return res;
}
/*龟速乘*/
LL gsc(LL a,lLL b,LL mod)
{
    LL res=0;
    for(;b;b>>=1,a=(a+a)%mod)if(b&1)res=(res+a)%mod;
    return res;
}
/*线性筛素数*/
for(int i=2;i<=M;++i)
{
	if(!vis[i])prime[++tot]=i;
	for(int j=1;j<=tot&&prime[j]*i<=M;++j)
	{
		vis[prime[j]*i]=1;
		if(!(i%prime[j]))break;
	}
}
/*线性筛phi函数*/
phi[1]=1;
for(int i=2;i<=M;++i) 
{
    if(!vis[i]) prime[++tot]=i,phi[i]=i-1;
	for(int j=1;j<=tot&&i*p[j]<=M;++j) 
    {
        vis[i*prime[j]]=1;
        if(!(i%prime[j])) 
        {
            phi[i*prime[j]]=phi[i]*prime[j];
            break;
        }
        phi[i*prime[j]]=phi[i]*(prime[j]-1);
    }
} 
/*约数个数*/
/*
he表示i的约数个数  num表示i的最小素因子的个数
*/
he[1]=1;vis[1]=1;num[1]=1;
for(int i=2;i<=M;++i)
{
	if(!vis[i])
	{
		zhi[++tot]=i;
		he[i]=2;num[i]=1;
	}
	for(int j=1;j<=tot&&zhi[j]*i<=M;++j)
	{
		vis[zhi[j]*i]=1;
		if(!(i%zhi[j]))
		{
			num[i*zhi[j]]=num[i]+1;
			he[zhi[j]*i]=he[i]/(num[i]+1)*(num[i*zhi[j]]+1);
			break;
		}
		else 
		{
			num[i*zhi[j]]=1;
			he[zhi[j]*i]=he[zhi[j]]*he[i];
		}
	}
} 
/*约数和*/
/*
yh表示i的约数和 xh表示i的最小素因子的等比数列的和
*/
yh[1]=xh[1]=1;
for(register int i=2;i<=M;++i)
{
	if(!vis[i])
	{
		zhi[++tot]=i;
		yh[i]=i+1;xh[i]=i+1;
	}
	for(register int j=1;j<=tot&&zhi[j]*i<=M;++j)
	{
		vis[i*zhi[j]]=1;
		if(!(i%zhi[j]))
		{
			yh[i*zhi[j]]=yh[i]/xh[i]*(xh[i]*zhi[j]+1);
			xh[i*zhi[j]]=xh[i]*zhi[j]+1;
			break;
		}
		yh[i*zhi[j]]=yh[i]*yh[zhi[j]];
		xh[i*zhi[j]]=zhi[j]+1;
	}
}
for(register int i=1;i<=M;++i)
xh[i]=xh[i-1]+yh[i];
/*根号求phi*/
/*
a和m互质时,a^{phi(m)} == 1 mod m
b>=phi(m)时,a^b ==  a^{(b mod phi(m)) + phi(m)} mod m
*/
LL solve_phi(LL x)
{
	LL res=x;
	for(int i=2;i*i<=x;++i)
		if(!(x%i))
		{
			res=res-res/i;
			while(!(x%i))x/=i;
		}
	if(x!=1)res=res-res/x;
	return res;
}
/*DIJ单源最短路*/
struct dian
{
	int hao,dis;
	friend bool operator <(const dian &a,const dian &b)
	{return a.dis>b.dis;}
};
priority_queue<dian>q;
memset(dis,0x3f,sizeof dis);
dis[s]=0;
q.push(dian{s,0});
while(!q.empty())
{
	x=q.top().hao;q.pop();
	if(vis[x])continue;
	vis[x]=1;
	for(int i=head[x];i;i=e[i].nt)
		if(dis[e[i].to]>dis[x]+e[i].dis)
		{
			dis[e[i].to]=dis[x]+e[i].dis;
			q.push(dian{e[i].to,dis[e[i].to]});
		}
}
/*SPFA*/
memset(dis,0x3f,sizeof dis);
dis[s]=0;
q.push(s);vis[s]=1;
while(!q.empty())
{
	x=q.front;q.pop();vis[x]=0;
	for(int i=head[x];i;i=e[i].nt)
	{
		if(dis[e[i].to]>dis[x]+e[i].dis)
		{
			dis[e[i].to]=dis[x]+e[i].dis;
			if(!vis[e[i].to])
			{
				q.push(e[i].to);
				vis[e[i].to]=1;
			}
		}
	}
}
/*快读*/
inline int read()
{
	int res=0;char ch=getchar();bool XX=false;
	for(;!isdigit(ch);ch=getchar())(ch=='-')&&(XX=true);
	for(; isdigit(ch);ch=getchar())res=(res<<3)+(res<<1)+(ch^48);
	return XX?-res:res;
}
/*快输*/
/*注意不能输出负数和0!*/
void Write(LL x)
{
	if(!x)return;
	Write(x/10);
	putchar((x-x/10*10)+'0');
}
/*倍增求LCA*/
void yych(int x,int f)
{
	dep[x]=dep[f]+1;fa[x][0]=f;
	
	for(int i=1;(1<<i)<=dep[x];++i)
	fa[x][i]=fa[fa[x][i-1]][i-1];
	
	for(int i=head[x];i;i=e[i].nt)
	if(e[i].to!=f)yych(e[i].to,x);
}
int LCA(int x,int y)
{
	if(dep[x]<dep[y])swap(x,y);
	for(int i=21;i>=0;--i)
	if(dep[x]-(1<<i)>=dep[y])x=fa[x][i];
	
	if(x==y)return x;
	
	for(int i=21;i>=0;--i)
	{
		if(fa[x][i]==fa[y][i])continue;
		x=fa[x][i];y=fa[y][i];
	}
	return fa[x][0];
}
/*树链剖分*/
void dfs1(int x)
{
	siz[x]=1;
	for(int i=head[x];i;i=e[i].nt)
	{
		if(e[i].to==fa[x])continue;
		dep[e[i].to]=dep[x]+1;
		fa[e[i].to]=x;
		dfs1(e[i].to);
		siz[x]+=siz[e[i].to];
		if(siz[e[i].to]>siz[son[x]])son[x]=e[i].to;
	}
}
void dfs2(int x,int t)
{
	dfn[x]=++cnt;
	a[cnt]=val[x];
	top[x]=t;
	if(son[x])dfs2(son[x],t);
	else return;
	for(int i=head[x];i;i=e[i].nt)
	{
		if(e[i].to==fa[x]||e[i].to==son[x])continue;
		dfs2(e[i].to,e[i].to);
	}
}
/*快速排序*/
void my_sort(int l,int r)
{
	int ix=l,jx=r,mid=num[(l+r)>>1];
	do
	{
		while(num[ix]<mid)ix++;
		while(num[jx]>mid)jx--;
		if(ix<=jx)swap(num[ix++],num[jx--]);	
	}while(ix<=jx);
	if(l<jx)my_sort(l,jx);
	if(ix<r)my_sort(ix,r);
}
/*快速排序找第k大数*/
int qsort(int l,int r,int k)
{
	if(l==r)return a[l];
    int now1=l,now2=r,mid=a[(l+r)>>1];
    do
    {
        while(a[now1]<mid) now1++;
        while(a[now2]>mid) now2--;
        if(now1<=now2) swap(a[now1++],a[now2--]);
    }while(now1<=now2);
    if(l<now2&&k<=(now2-l+1)) return qsort(l,now2,k);
    else if(now1<r&&k>(now1-l)) return qsort(now1,r,k-(now1-l));
    else return a[l+k-1];
}
/*扩展欧几里得*/
void EXGCD(int a,int b,int &x,int &y)
{
	if(!b)
	{
		x=1;y=0;
		return;
	}
	EXGCD(b,a%b,x,y);
	int t=x;x=y;y=t-(a/b)*y;
}
/*中国剩余定理*/
/*a*m*t之和*/
cin>>n;
for(int i=1;i<=n;++i)scanf("%lld%lld",&p[i],&a[i]);
for(int i=1;i<=n;++i)M*=p[i];
for(int i=1;i<=n;++i)
{
	int l,k,j;
	m[i]=M/p[i];
	int lin=exgcd(m[i],p[i],l,j);
	(ans+=(a[i]*m[i]*l))%=M;
	ans=(ans+M)%M;
}
/*卢卡斯定理*/
/*L(n,m)==L(n/p,m/p)*C(n%p,m%p) (mod p)*/
LL lucas(LL n,LL m)
{
	if(!m)return 1;
	return lucas(n/mod,m/mod)*C(n%mod,m%mod)%mod;
}
/*二分*/
l=0;r=***;
while(l<=r)
{
	int mid=(l+r)>>1;
	if(check(mid))ans=mid,r=mid-1;
	else l=mid+1;
}
cout<<ans;
/*lowbit*/
int lowbit(int x){return x&(-x);}
/*树状数组查询*/
int ask(int pos)
{
	int res=0;
	for(;pos;pos-=lowbit(pos))res+=tr[pos];
	return res;
}
/*树状数组修改*/
void add(int pos,int val)
{
	for(;pos<=n;pos+=lowbit(pos))tr[pos]+=val;
}
/*KMP*/
int k=0;nt[1]=0;
for(int i=2;i<=lenb;++i)
{
	while(k&&b[k+1]!=b[i])k=nt[k];
	if(b[k+1]==b[i])++k;
	nt[i]=k;
}
k=0;
for(int i=1;i<=lena;++i)
{
	while(k&&b[k+1]!=a[i])k=nt[k];
	if(b[k+1]==a[i])++k;
	if(k==lenb)w[++ans]=i-lenb+1;
}
/*数论分块*/
for(int l=1,r;l<=k;l=r+1)
{ 
	r=k/(k/l);
}
/*线性求逆元*/
inv[1]=1;
for(int i=2;i<=n;++i)inv[i]=(p-(p/i))*inv[p%i]%p;
/*
定理1:存在欧拉路的条件:图是连通的,有且只有2个奇点.
定理2:存在欧拉回路的条件:图是连通的,有0个奇点.
*/
/*Kruskal最小生成树*/
struct bian
{
	int fr,to,dis;
	friend bool operator <(const bian &a,const bian &b){return a.dis<b.dis;}
}e[100010];
int find(int x){return x==fa[x]?fa[x]:fa[x]=find(fa[x]);}
void he(int x,int y){fa[find(x)]=fa[find(y)];}
cin>>n>>m;
for(int i=1;i<=n;++i)fa[i]=i;
for(int i=1;i<=m;++i)scanf("%d%d%d",&e[i].fr,&e[i].to,&e[i].dis);
sort(e+1,e+1+m);
for(int i=1;i<=m;++i)
{
	int x=find(e[i].fr),y=find(e[i].to);
	if(x==y)continue;
	he(x,y);
	++k;
	if(k==n-1)break;
}
/*二分图匹配*/
bool dfs(int x)
{
	for(int i=1;i<=m;++i)
		if(f[x][i]&&(!vis[i]))
		{
			vis[i]=1;
			if(!g[i]||dfs(g[i])){g[i]=x;return 1;}
		}
	return 0;	
}
cin>>n>>m>>e;
for(int i=1;i<=e;++i)
{
	scanf("%d%d",&x,&y);
	f[x][y]=1;
}
for(int i=1;i<=n;++i)
{
	memset(vis,0,sizeof(vis));
	if(dfs(i))++ans;
}
/*最长不下降子序列*/
d[1]=1;len=1;
for(int i=2;i<=n;++i)
{
	if(a[i]>=d[len])d[++len]=a[i];
	else *upper_bound(d+1,d+1+len,a[i])=a[i];
}
/*最长公共子序列*/
for(int i=1;i<=n;++i)scanf("%d",&a[i]);
for(int i=1;i<=n;++i)scanf("%d",&b[i]);
for(int i=1;i<=n;++i)
	for(int j=1;j<=n;++j)
	if(a[i]==b[j])fp[i][j]=max(dp[i][j],dp[i-1][j-1]+1);
	else dp[i][j]=max(dp[i-1][j],dp[i][j-1]);
/*01背包*/
cin>>V>>n;
for(int i=1;i<=n;++i)scanf("%d%d",&w[i],&k[i]);
for(int i=1;i<=n;++i)
	for(int j=V;j>=w[i];--j)
	f[j]=max(f[j],f[j-w[i]]+k[i]);
cout<<f[V];
/*完全背包*/
for(int j=w[i];j<=V;j++)
/*分组背包*/
for(int i=1;i<=100;i++)
  if(t[i].size())
    {
        p=t[i].size();
        for(int j=m;j>=0;j--)
           for(int k=0;k<p;k++)
              if(j>=t[i][k].weight) dp[j]=max(dp[j],dp[j-t[i][k].weight]+t[i][k].value);
    }
/*动态开点线段树 & 线段树合并*/
void change(int &k,int l,int r,int pos,int val)
{
	if(!k)k=++cnt;
	if(l==r)
	{
		maxx[k]+=val ;wi[k]=l;
		return;
	}
	if(pos<=mid)change(lson[k],l,mid,pos,val);
	else change(rson[k],mid+1,r,pos,val);
	
	maxx[k]=max(maxx[lson[k]],maxx[rson[k]]);
	if(maxx[lson[k]]>=maxx[rson[k]])wi[k]=wi[lson[k]];
	else wi[k]=wi[rson[k]];
}
int he(int p,int q,int l,int r)
{
	if((!p)||(!q))return p+q;
	if(l==r)
	{
		maxx[p]+=maxx[q];
		return p;
	}
	lson[p]=he(lson[p],lson[q],l,mid);
	rson[p]=he(rson[p],rson[q],mid+1,r);
	
	maxx[p]=max(maxx[lson[p]],maxx[rson[p]]);
	if(maxx[lson[p]]>=maxx[rson[p]])wi[p]=wi[lson[p]];
	else wi[p]=wi[rson[p]];
	return p;
}
/*ST表*/
int ask(int l, int r) 
{
	int g = log2(r - l + 1);
	return max(a[l][g], a[r - (1 << g) + 1][g]);
}
for (int i = 1; i <= n; ++i)a[i][0] = read();
for (int j = 1; j <= 24; ++j)
	for (int i = 1; i + (1 << j) <= n + 1; ++i)
		a[i][j] = max(a[i][j - 1], a[i + (1 << (j - 1))][j - 1]);
/*ODT*/
#define IT set<node>::iterator
struct node
{
	int l,r;
	mutable int val;
	node(int L,int R=-1,int V=0):l(L),r(R),val(V){}
	friend bool operator <(const node &a,const node &b)
	{return a.l<b.l;}
}
set<node>s;
IT split(int pos)
{
	IT it=s.lower_bound(node(pos));
	if(it!=s.end()&&it->l==pos)return it;
	--it;
	int L=it->l,R=it->r;
	long long V=it->val;
	s.erase(it);
	s.insert(node{L,pos-1,V});
	return s.insert(node{pos,R,V}).first;
}
void tuiping(int l,int r,int v)
{
	IT it2=split(r+1),it1=split(l);
	s.erase(it1,it2);
	s.insert(node{l,r,v});
}
void add(int l,int r,int v)
{
	IT it2=split(r+1),it1=split(l);
	for(;it1!=it2;++it1)it1->val+=v;
}
long long ask(int l,int r,int x,int mod)
{
	IT it2=split(r+1),it1=split(l);
	long long res=0;
	for(;it1!=it2;++it1)
	res=(res+(long long)(it1->r-it1->l+1)*ksm(it1->val,(long long) (x),(long long) (mod)))%mod;
	return res;
}
/*三分*/
while(r-l>0.000001)
{
	 double m1=l+(r-l)/3;
	 double m2=r-(r-l)/3;
	 if(check(m1)>check(m2)) r=m2;
	 else l=m1;
}
/*普通Trie树*/
void Insert(int val)
{
	int t,a=0;
	for(int i=30;i>=1;--i)
	{
		t=(val&(1<<(i-1)))>>(i-1);
		if(!tr[a][t])tr[a][t]=++cnt;
		a=tr[a][t];
	}
}
int ask(int val)
{
	int t,a=0,res=0;
	for(int i=30;i>=1;--i)
	{
		t=(val&(1<<(i-1)))>>(i-1);
		if(tr[a][!t])
		{
			res+=(1<<(i-1));
			a=tr[a][!t];
		}
		else a=tr[a][t];
	}
	return res;
}
/*manacher 马拉车*/
scanf("%s", b + 1);
lenb = strlen(b + 1);
for (int i = 1; i <= lenb; ++i)a[i << 1] = b[i];
lena = lenb * 2 + 1;
for (int i = 1; i <= lena; i = i + 2)a[i] = '*';
for (int i = 1; i <= lena; ++i) 
{
	bj = 1;
	if (r < i) 
	{
		r = i; hao = i; bj = 1;
	} 
	else bj = min(r - i + 1, p[2 * hao - i]);
	while (i + bj <= lena && i - bj >= 1 && a[i + bj] == a[i - bj])bj++;
	p[i] = bj;
	if (i + bj - 1 > r) 
	{
		r = i + bj - 1; hao = i;
	}
	ans = max(ans, p[i] - 1);
}