染色数组

Posted PYWBKTDA

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了染色数组相关的知识,希望对你有一定的参考价值。

定义集合\\(S\\)由同时满足以下条件的\\(x\\)构成:

  • \\([1,x)\\)\\(\\le a_x\\)的元素 和 \\((x,n]\\)\\(\\ge a_x\\)的元素 构成递增子序列
  • \\([1,x)\\)\\(\\ge a_x\\)的元素 和 \\((x,n]\\)\\(\\le a_x\\)的元素 构成递减子序列

性质1:\\(a\\)为完美数组当且仅当\\(S\\ne \\empty\\)

必要性:注意\\(x\\in S\\)\\(x\\)可以染成红色和绿色的必要条件

充分性:任取\\(x\\in S\\),将条件中第\\(1\\)类元素染成红色,其余染成绿色即可

性质2:\\(x\\in S\\),则\\(x+1\\in S\\iff \\forall i\\in [1,x),a_i\\not\\in [a_x,a_y]\\cup [a_y,a_x]\\)

性质3:\\(\\begincasesl=\\min_x\\in Sx\\\\r=\\max_x\\in Sx\\endcases\\),则\\(S=[l,r]\\cap Z\\)且满足以下条件之一

  • \\(l+1=r\\)\\(a_l=a_r\\)
  • \\(a_l<a_l+1<...<a_r\\)\\(a_l>a_l+1>...>a_r\\)

(证明可以自行分类讨论得到)

为了方便,以下均假设为第\\(2\\)种情况,第\\(1\\)种情况是类似的


根据性质\\(3\\),在\\(r\\)处统计方案数,即要求\\(r+1\\not\\in S\\),这可以用性质\\(2\\)判定

注意到对于\\(a_[1,r)\\),恰存在一种染色方式使得红色的结尾\\(<a_r\\)且绿色的结尾\\(>a_r\\)

定义\\(f_i,x,y\\)表示前\\(i\\)个位置中两序列结尾分别为\\(x,y\\)的方案数,转移易优化至\\(O(nm^2)\\),后缀类似

枚举\\(r,a_r\\)\\(a_r+1\\)后,即求形如\\(\\sum_x\\le x_0\\sum_y\\ge y_0f_i,x,y\\),预处理即可,时间复杂度为\\(O(tnm^2)\\)


性质4:得分最大的染色方案形如

  • \\([1,r)\\)\\(\\le a_r\\)的元素 和 \\((r,n]\\)\\(\\ge a_r\\)的元素 染成红色
  • \\([1,r)\\)\\(\\ge a_r\\)的元素 和 \\((r,n]\\)\\(\\le a_r\\)的元素 染成绿色
  • \\(a_r\\)的颜色取染红色或绿色中的较大值

此时,将贡献拆开,得分分为以下几部分:

  • \\(a_[1,r)\\)中,用\\(g/g0/g1_i,x,y\\)表示……的得分和、红色数和 和 绿色数和 即可

  • \\(a_r\\)中,用\\(f\'_i,z,x,y\\)表示在\\(f_i,x,y\\)的基础上红色有\\(z\\)个的方案数即可

  • \\(a_(r,n]\\)中,其内部无贡献,仅与\\(a_[1,r)\\)之间有贡献

    以染成红色的\\(a_i\\)为例,即统计\\(a_[1,r)\\)\\(>a_i\\)的元素个数,枚举\\(a_i\\)即可

时间复杂度为\\(O(tn^2m^2+tnm^3)\\),大概不是很对,但卡卡常应该能过(雾

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=55,M=205,mod=998244353;
int t,n,m,n0,ans1,ans2,a[N];
int fs[N][M][M],Fp[N][N][M][M],gp0[N][M][M],gp1[N][M][M],gs[N][M][M];
int add(int x,int y)
	x+=y;
	return (x<mod ? x : x-mod);

struct Data
	int f,g,g0,g1;
	Data upd0(int x)
		return Dataf,(int)((g+(ll)x*g0)%mod),g0,add(f,g1);
	
	Data upd1(int x)
		return Dataf,(int)((g+(ll)(m-x+1)*g1)%mod),add(f,g0),g1;
	
fp[N][M][M];
Data add(Data x,Data y)
	return Dataadd(x.f,y.f),add(x.g,y.g),add(x.g0,y.g0),add(x.g1,y.g1);

Data dec(Data x,Data y)
	return Dataadd(x.f,mod-y.f),add(x.g,mod-y.g),add(x.g0,mod-y.g0),add(x.g1,mod-y.g1);

void get_sum(Data a[M][M])
	for(int i=0;i<=m;i++)
		for(int j=m+1;j>i;j--)
			if (i)a[i][j]=add(a[i][j],a[i-1][j]);
			if (j<=m)a[i][j]=add(a[i][j],a[i][j+1]);
			if ((i)&&(j<=m))a[i][j]=dec(a[i][j],a[i-1][j+1]);
		

void get_fp()
	memset(fp,0,sizeof(fp));
	for(int x=0;x<=m;x++)
		for(int y=x+1;y<=m+1;y++)fp[0][x][y]=Data1,0,0,0;
	for(int i=1;i<=n;i++)
		for(int j=1;j<=m;j++)
			if ((i<=n0)&&(a[i]!=j))continue;
			for(int x=0;x<j;x++)
				fp[i][x][j]=add(fp[i][x][j],fp[i-1][x][j+1].upd0(j));
				if (x)fp[i][x][j]=dec(fp[i][x][j],fp[i-1][x-1][j+1].upd0(j));
			
			for(int y=j+1;y<=m+1;y++)
				fp[i][j][y]=add(fp[i][j][y],fp[i-1][j-1][y].upd1(j));
				if (y<=m)fp[i][j][y]=dec(fp[i][j][y],fp[i-1][j-1][y+1].upd1(j));
			
		
		get_sum(fp[i]);
	

void get_sum(int a[M][M])
	for(int i=0;i<=m;i++)
		for(int j=m+1;j>i;j--)
			if (i)a[i][j]=add(a[i][j],a[i-1][j]);
			if (j<=m)a[i][j]=add(a[i][j],a[i][j+1]);
			if ((i)&&(j<=m))a[i][j]=add(a[i][j],mod-a[i-1][j+1]);
		

void get_fs()
	memset(fs,0,sizeof(fs));
	for(int x=0;x<=m;x++)
		for(int y=x+1;y<=m+1;y++)fs[n+1][x][y]=1;
	for(int i=n;i;i--)
		for(int j=1;j<=m;j++)
			if ((i<=n0)&&(a[i]!=j))continue;
			for(int x=0;x<j;x++)
				fs[i][x][j]=add(fs[i][x][j],fs[i+1][x][j+1]);
				if (x)fs[i][x][j]=add(fs[i][x][j],mod-fs[i+1][x-1][j+1]);
			
			for(int y=j+1;y<=m+1;y++)
				fs[i][j][y]=add(fs[i][j][y],fs[i+1][j-1][y]);
				if (y<=m)fs[i][j][y]=add(fs[i][j][y],mod-fs[i+1][j-1][y+1]);
			
		
		get_sum(fs[i]);
	

void get_Fp()
	memset(Fp,0,sizeof(Fp));
	for(int x=0;x<=m;x++)
		for(int y=x+1;y<=m+1;y++)Fp[0][0][x][y]=1; 
	for(int i=1;i<=n;i++)
		for(int z=0;z<=i;z++)
			for(int j=1;j<=m;j++)
				if ((i<=n0)&&(a[i]!=j))continue;
				for(int x=0;x<j;x++)
					Fp[i][z][x][j]=add(Fp[i][z][x][j],Fp[i-1][z][x][j+1]);
					if (x)Fp[i][z][x][j]=add(Fp[i][z][x][j],mod-Fp[i-1][z][x-1][j+1]);
				
				if (z)
					for(int y=j+1;y<=m+1;y++)
						Fp[i][z][j][y]=add(Fp[i][z][j][y],Fp[i-1][z-1][j-1][y]);
						if (y<=m)Fp[i][z][j][y]=add(Fp[i][z][j][y],mod-Fp[i-1][z-1][j-1][y+1]);
					
				
			
			get_sum(Fp[i][z]);
		

void get_gp(int w)
	memset(gp0,0,sizeof(gp0));
	memset(gp1,0,sizeof(gp1));
	for(int i=1;i<=n;i++)
		for(int j=1;j<=m;j++)
			if ((i<=n0)&&(a[i]!=j))continue;
			for(int x=0;x<j;x++)
				gp0[i][x][j]=add(gp0[i][x][j],gp0[i-1][x][j+1]);
				gp1[i][x][j]=add(gp1[i][x][j],gp1[i-1][x][j+1]);
				if (x)
					gp0[i][x][j]=add(gp0[i][x][j],mod-gp0[i-1][x-1][j+1]);
					gp1[i][x][j]=add(gp1[i][x][j],mod-gp1[i-1][x-1][j+1]);
				
			
			for(int y=j+1;y<=m+1;y++)
				gp0[i][j][y]=add(gp0[i][j][y],gp0[i-1][j-1][y]);
				gp1[i][j][y]=add(gp1[i][j][y],gp1[i-1][j-1][y]);
				if (y<=m)
					gp0[i][j][y]=add(gp0[i][j][y],mod-gp0[i-1][j-1][y+1]);
					gp1[i][j][y]=add(gp1[i][j][y],mod-gp1[i-1][j-1][y+1]);
				
			
			if (j<w)
				for(int x=0;x<j;x++)
					gp0[i][x][j]=(gp0[i][x][j]+(ll)w*fp[i-1][x][j+1].f)%mod;
					if (x)gp0[i][x][j]=(gp0[i][x][j]+(ll)w*(mod-fp[i-1][x-1][j+1].f))%mod;
				
				for(int y=j+1;y<=m+1;y++)
					gp0[i][j][y]=(gp0[i][j][y]+(ll)w*fp[i-1][j-1][y].f)%mod;
					if (y<=m)gp0[i][j][y]=(gp0[i][j][y]+(ll)w*(mod-fp[i-1][j-1][y+1].f))%mod;
				
			
			if (j>w)
				for(int x=0;x<j;x++)
					gp1[i][x][j]=(gp1[i][x][j]+(ll)(m-w+1)*fp[i-1][x][j+1].f)%mod;
					if (x)gp1[i][x][j]=(gp1[i][x][j]+(ll)(m-w+1)*(mod-fp[i-1][x-1][j+1].f))%mod;
				
				for(int y=j+1;y<=m+1;y++)
					gp1[i][j][y]=(gp1[i][j][y]+(ll)(m-w+1)*fp[i-1][j-1][y].f)%mod;
					if (y<=m)gp1[i][j][y]=(gp1[i][j][y]+(ll)(m-w+1)*(mod-fp[i-1][j-1][y+1].f))%mod;
				
			
		
		get_sum(gp0[i]),get_sum(gp1[i]);
	

void get_gs(int w)
	memset(gs,0,sizeof(gs));
	for(int i=n;i;i--)
		for(int j=1;j<=m;j++)
			if ((i<=n0)&&(a[i]!=j))continue;
			for(int x=0;x<j;x++)
				gs[i][x][j]=add(gs[i][x][j],gs[i+1][x][j+1]);
				if (x)gs[i][x][j]=add(gs[i][x][j],mod-gs[i+1][x-1][j+1]);
			
			for(int y=j+1;y<=m+1;y++)
				gs[i][j][y]=add(gs[i][j][y],gs[i+1][j-1][y]);
				if (y<=m)gs[i][j][y]=add(gs[i][j][y],mod-gs[i+1][j-1][y+1]);
			
			if (j==w)
				for(int x=0;x<j;x++)
					gs[i][x][j]=add(gs[i][x][j],fs[i+1][x][j+1]);
					if (x)gs[i][x][j]=add(gs[i][x][j],mod-fs[i+1][x-1][j+1]);
				
				for(int y=j+1;y<=m+1;y++)
					gs[i][j][y]=add(gs[i][j][y],fs[i+1][j-1][y]);
					if (y<=m)gs[i][j][y]=add(gs[i][j][y],mod-fs[i+1][j-1][y+1]);
				
			
		
		get_sum(gs[i]);
	

int main()
	scanf("%d",&t);
	while (t--)
		scanf("%d%d%d",&n,&m,&n0);
		for(int i=1;i<=n0;i++)scanf("%d",&a[i]);
		ans1=ans2=0;
		get_fp(),get_fs(),get_Fp();
		for(int i=1;i<n;i++)
			for(int j=1;j<=m;j++)
				if ((i<=n0)&&(a[i]!=j)||(i<n0)&&(a[i+1]!=j))continue;
				int s=fs[i+2][j-1][j+1];
				ans1=(ans1+(ll)fp[i-1][j-1][j+1].f*s)%mod;
				ans2=(ans2+(ll)fp[i-1][j-1][j+1].g*s)%mod;
				for(int z=0;z<i;z++)ans2=(ans2+(ll)(z*j+(i-z-1)*(m-j+1))*Fp[i-1][z][j-1][j+1]%mod*s)%mod;
			
		for(int i=1;i<=m;i++)
			if ((n<=n0)&&(a[n]!=i))continue;
			ans1=add(ans1,fp[n-1][i-1][i+1].f);
			ans2=add(ans2,fp[n-1][i-1][i+1].g);
			for(int z=0;z<n;z++)ans2=(ans2+(ll)max(z*i,(n-z-1)*(m-i+1))*Fp[n-1][z][i-1][i+1])%mod;
		
		for(int i=1;i<n;i++)
			for(int x=1;x<=m;x++)
				if ((i<=n0)&&(a[i]!=x))continue;
				for(int y=1;y<=m;y++)
					if ((i<n0)&&(a[i+1]!=y))continue;
					if (y<x)
						int s=fs[i+2][y-1][x+1];
						Data o=dec(fp[i-1][x-1][x+1],fp[i-1][y-1][x+1]);
						ans1=(ans1+(ll)o.f*s)%mod,ans2=(ans2+(ll)o.g*s)%mod;
						for(int z=0;z<i;z++)ans2=(ans2+(ll)max(z*x,(i-z-1)*(m-x+1))*(Fp[i-1][z][x-1][x+1]+mod-Fp[i-1][z][y-1][x+1])%mod*s)%mod;
					
					if (y>x)
						int s=fs[i+2][x-1][y+1];
						Data o=dec(fp[i-1][x-1][x+1],fp[i-1][x-1][y+1]);
						ans1=(ans1+(ll)o.f*s)%mod,ans2=(ans2+(ll)o.g*s)%mod;
						for(int z=0;z<i;z++)ans2=(ans2+(ll)max(z*x,(i-z-1)*(m-x+1))*(Fp[i-1][z][x-1][x+1]+mod-Fp[i-1][z][x-1][y+1])%mod*s)%mod;
					
				
			
		for(int w=1;w<=n;w++)
			get_gp(w),get_gs(w);
			for(int i=1;i<n;i++)
				for(int j=1;j<=m;j++)
					if ((i<=n0)&&(a[i]!=j)||(i<n0)&&(a[i+1]!=j))continue;
					ans2=(ans2+(ll)(w<j ? (ll)gp0[i-1][j-1][j+1] : gp1[i-1][j-1][j+1])*gs[i+2][j-1][j+1])%mod;
				
			for(int i=1;i<n;i++)
				for(int x=1;x<=m;x++)
					if ((i<=n0)&&(a[i]!=x))continue;
					for(int y=1;y<=m;y++)
						if ((i<n0)&&(a[i+1]!=y))continue;
						if (y<x)
							int g0=add(gp0[i-1][x-1][x+1],mod-gp0[i-1][y-1][x+1]);
							int g1=add(gp1[i-1][x-1][x+1],mod-gp1[i-1][y-1][x+1]);
							ans2=(ans2+(ll)(w<x ? g0 : g1)*(gs[i+2][y-1][x+1]+(y==w ? fs[i+2][y-1][x+1] : 0)))%mod;
						
						if (y>x)
							int g0=add(gp0[i-1][x-1][x+1],mod-gp0[i-1][x-1][y+1]);
							int g1=add(gp1[i-1][x-1][x+1],mod-gp1[i-1][x-1][y+1]);
							ans2=(ans2+(ll)(w<x ? g0 : g1)*(gs[i+2][x-1][y+1]+(y==w ? fs[i+2][x-1][y+1] : 0)))%mod;
						
					
				
		
		printf("%d %d\\n",ans1,ans2);
	
	return 0;

8/11 二分图染色+KM算法变型+后缀数组+图论

P6185 [NOI Online #1 提高组] 序列

又因为一个小错误浪费了1个半小时。。。我是真的sb啊!
题意:将数组a经过两种操作使得和b数组相等:
操作1:将a数组中,i和j两个下标的数同时加1或者减1.
操作2:将a数组上两个下标值一个加1一个减一,或者一个减1一个加1
思路:
1.操作2一个加1一个减1,但两个数总和不变,由于该操作的传递性,可形成一个连通块,在此连通块内可任意调整值。可理解为缩点操作
2.操作1对数组a同时加1或减1,可转化为a部点加1,b部点减1,或相反。
若是二分图,则a部点值之和要等于b部点权值之和
若非二分图,则此时只对数组a操作,不涉及操作2,要保证操作前前后奇偶行相同,因为每次操作都是加2或者减去2.

#include<bits/stdc++.h>
#define int long long
#define endl '\\n'

using namespace std;
const int N=7e5+10;
const int inf=0x3f3f3f3f;
int n,m,a[N],b[N],f[N],p[N],q[N],g,sz[N],num[3],col[N];
vector<int>e[N];
int r_find(int r)

    return r==f[r]?r:(f[r]=r_find(f[r]));

bool dfs(int x,int c)

    col[x]=c,num[c]+=sz[x];
    int flag=1;
    for(int i=0;i<e[x].size();i++)
    
        int y=e[x][i];
        if(col[y]==col[x]) flag=0;
        if(!col[y]&&!dfs(y,3-c))
            flag=0;
    
    return flag;

int solve()

    cin>>n>>m;
    for(int i=1;i<=n;i++) cin>>a[i];
    for(int i=1;i<=n;i++) cin>>b[i];
    g=0;
    for(int i=1;i<=n;i++)
        f[i]=i,col[i]=sz[i]=0,e[i].clear();
    for(int i=1,op,x,y;i<=m;i++)
    
        cin>>op>>x>>y;
        if(op==2) f[r_find(x)]=r_find(y);
        else p[++g]=x,q[g]=y;
    
    for(int i=1;i<=n;i++)
        sz[r_find(i)]+=b[i]-a[i];
    for(int i=1;i<=g;i++)
    
        int x=r_find(p[i]),y=r_find(q[i]);
        e[x].push_back(y),e[y].push_back(x);
    
    for(int i=1;i<=n;i++)
    
        if(i==r_find(i)&&!col[i])
        
            num[1]=num[2]=0;
            bool flag=dfs(i,1);
            if(flag && num[1]!=num[2]) return 0;
            if(!flag && ((num[1]^num[2])&1)) return 0;
        
    
    return 1;

signed main()

    int t;cin>>t;
    while(t--)
    
        if(solve())
            cout<<"YES"<<endl;
        else
            cout<<"NO"<<endl;
    
    return 0;

P3967 [TJOI2014]匹配

题意:求出男女生间的求出最大匹配和最小匹配
最大匹配:带入模板求出最大完美匹配。
最小匹配:将权值取为负值,最后将答案进行取反操作

#include<bits/stdc++.h>
#define int long long
#define endl '\\n'
#define For(i,a,b) for(i=(a);i<=(b);++i)
#define ios (ios::sync_with_stdio(false),cin.tie(0),cout.tie(0))
using namespace std;
const int N=5e2+5;
const int inf=0x3f3f3f3f;
int match[N];       //右部点匹配了哪个左部点
int va[N],vb[N];    //标记是否在交替路中
int la[N],lb[N];    //左顶标、右顶标的值
int w[N][N],d[N];   //维护更新的delta值
int n,a[N][N];
bool dfs(int x)

    va[x]=1;
    for(int y=1;y<=n;y++)
    
        if(!vb[y])
        
            if(la[x]+lb[y]-w[x][y]==0)
            
                vb[y]=1;
                if(!match[y]||dfs(match[y]))
                
                    match[y]=x;return 1;
                
            
            else //不是相等子图则记录i最小的d[y]
                d[y]=min(d[y],la[x]+lb[y]-w[x][y]);
        
    
    return 0;

int KM()

    //预处理
    for(int i=1;i<=n;i++) la[i]=-inf;
    for(int i=1;i<=n;i++)
        for(int j=1;j<=n;j++)
        la[i]=max(la[i],w[i][j]);
    for(int i=1;i<=n;i++)
        lb[i]=0;
    for(int i=1;i<=n;i++)
    
        while(1)
        
            fill(va+1,va+n+1,0);
            fill(vb+1,vb+n+1,0);
            fill(d+1,d+n+1,inf);
            if(dfs(i)) break;
            int delta=inf;
            for(int j=1;j<=n;j++)
                if(!vb[j]) delta=min(delta,d[j]);
            for(int j=1;j<=n;j++)
            
                if(va[j]) la[j]-=delta;
                if(vb[j]) lb[j]+=delta;
            
        
    
    int res=0;
    for(int i=1;i<=n;i++)
        res+=w[match[i]][i];
    return res;


void solve()

    memset(w,-inf,sizeof w);
    cin>>n;
    for(int i=1;i<=n;i++)
        for(int j=1;j<=n;j++)
            cin>>w[i][j],a[i][j]=w[i][j],w[i][j]=-w[i][j];
    cout<<-KM()<<endl;
    memset(match,0,sizeof match);
    memset(w,-inf,sizeof w);
    for(int i=1;i<=n;i++)
        for(int j=1;j<=n;j++)
            w[i][j]=a[i][j];
    cout<<KM()<<endl;

signed main()

    //ios;
    solve();
    return 0;


P6140 [USACO07NOV]Best Cow Line S

属于范围0~2000,n^2的方法可以,但若是1e5就得用后缀数组了qaq
直接贪心即可。贪心策略真的太典了,不说了

#include<bits/stdc++.h>
#define int long long
#define endl '\\n'

using namespace std;
const int N=7e5+10;
const int inf=0x3f3f3f3f;
int n;
string s;
void solve()

    cin>>n;
    string s1=" ";
    for(int i=1;i<=n;i++)
    
        string s;cin>>s;
        s1+=s;
    
    string s2="";
    for(int i=1,j=n;i<=j;)
    
        if(i==j)
        
            s2+=s1[i];break;
        
        if(s1[i]<s1[j]) s2+=s1[i],i++;
        else if(s1[i]>s1[j]) s2+=s1[j],j--;
        else
        
            int a1=i,a2=j;
            while(s1[a1]==s1[a2]&&a1<a2)
                a1++,a2--;
            if(s1[a1]<s1[a2]) s2+=s1[i],i++;
            else if(s1[a1]>s1[a2]) s2+=s1[j],j--;
            else
                s2+=s1[i],i++;
        
    
    for(int i=0;i<n;i++)
    
        if(i%80==0&&i!=0)
            cout<<endl;
        cout<<s2[i];
    
    cout<<endl;

signed main()

    solve();
    return 0;


P2870 [USACO07DEC]Best Cow Line G

数据范围5e5次方,应使用后缀数组来解决问题了。
得换一个模板了,此模板复杂度有点高,最后一组样例卡住了。
思路:
由于需要比较由前后字母向中间延申直至不同字符的字符串大小,因此想到构造一个新的字符串。
AACBAA —> AACBAA#AABCAA
(一个非常重要而技巧,将前缀转化为后缀)
比较rk[l]rk[2*(n+1)-r]

#include<bits/stdc++.h>
#define endl '\\n'
#define re register
using namespace std;
const int N=7e6+10;
const int inf=0x3f3f3f3f;
int n,k;
int rk[N],rk2[N];   //以i开头后缀的排名
char s[N],s1[N],str[N];
int sa[N];   //表示sa[i]表示排名i的后缀的开头下标

//求解各个以i为起始下标的后缀字符串的排名
inline bool cmp(re int i,re int j)

    if(rk[i]!=rk[j])
        return rk[i]<rk[j];
    int ri=(i+k<=n ? rk[i+k]:-1);
    int rj=(j+k<=n ? rk[j+k]:-1);
    return ri<rj;

inline void getsa(int n,char *str)

    for(re int i=1;i<=n;i++)
        sa[i]=i,rk[i]=s[i];  //利用ASCLL码
    for(k=1;k<=n;k*=2)
    
        sort(sa+1,sa+1+n,cmp);
        rk2[sa[1]]=1;
        for(int i=2;i<=n;i++)
            rk2[sa[i]]=rk2[sa[i-1]]+cmp(sa[i-1],sa[i]);
        for(int i=1;i<=n;i++)
            rk[i]=rk2[i];
    



inline void solve()

    scanf("%d",&n);
    for(re int i以上是关于染色数组的主要内容,如果未能解决你的问题,请参考以下文章

P2161 [SHOI2009]会场预约 - 线段树染色

洛谷 P2486 [SDOI2011]染色

图染色的禁忌算法

贴海报 (线段树染色-离散化

May LeetCoding Challenge27 之 二分图

May LeetCoding Challenge27 之 二分图