直接按父亲分类,计算最大次大值
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
using namespace std;
#define For(i,n) for(int i=1;i<=n;i++)
#define Fork(i,k,n) for(int i=k;i<=n;i++)
#define ForkD(i,k,n) for(int i=n;i>=k;i--)
#define Rep(i,n) for(int i=0;i
#define ForD(i,n) for(int i=n;i;i--)
#define RepD(i,n) for(int i=n;i>=0;i--)
#define Forp(x) for(int p=pre[x];p;p=next[p])
#define Forpiter(x) for(int &p=iter[x];p;p=next[p])
#define Lson (o<<1)
#define Rson ((o<<1)+1)
#define MEM(a) memset(a,0,sizeof(a));
#define MEMI(a) memset(a,0x3f,sizeof(a));
#define MEMi(a) memset(a,128,sizeof(a));
#define MEMx(a,b) memset(a,b,sizeof(a));
#define INF (0x3f3f3f3f)
#define F (1000000007)
#define pb push_back
#define mp make_pair
#define fi first
#define se second
#define vi vector
#define pi pair
#define SI(a) ((a).size())
#define Pr(kcase,ans) printf("Case #%d: %lld\n",kcase,ans);
#define PRi(a,n) For(i,n-1) cout<
#define PRi2D(a,n,m) For(i,n) { \
For(j,m-1) cout<' ';\
cout<#pragma comment(linker, "/STACK:102400000,102400000")
#define ALL(x) (x).begin(),(x).end()
#define gmax(a,b) a=max(a,b);
#define gmin(a,b) a=min(a,b);
typedef long long ll;
typedef long double ld;
typedef unsigned long long ull;
ll mul(ll a,ll b){return (a*b)%F;}
ll add(ll a,ll b){return (a+b)%F;}
ll sub(ll a,ll b){return ((a-b)%F+F)%F;}
void upd(ll &a,ll b){a=(a%F+b%F)%F;}
inline int read()
{
int x=0,f=1; char ch=getchar();
while(!isdigit(ch)) {if (ch=='-') f=-1; ch=getchar();}
while(isdigit(ch)) { x=x*10+ch-'0'; ch=getchar();}
return x*f;
}
#define MAXN (112345)
int T;
int f[MAXN][2]={};
int fa[MAXN];
set<int> e[MAXN];
ll v[MAXN];
int cmp(ll a,ll b){
return a>b;
}
int main()
{
// freopen("b.in","r",stdin);
// freopen(".out","w",stdout);
int T=read();
while(T--) {
int n=read();
Fork(i,2,n) fa[i]=read();
For(i,n) v[i]=read();
fa[1]=0;
For(i,n) e[fa[i]].p(v[i]);
Rep(i,n+1) sort(ALL(e[i]),cmp);
ll ans=0,ansp=0;
Rep(i,n+1) {
int sz=SI(e[i]);
if(!sz) continue;
if(sz>=1) {
if(e[i][0]>0) ans+=e[i][0];
if(sz>=2) gmax(ansp,(ll)e[i][1])
}
}
printf("%I64d ",ans+ansp);
ans=0,ansp=0;
Rep(i,n+1) Rep(j,SI(e[i])) e[i][j]=-e[i][j];
Rep(i,n+1) reverse(ALL(e[i]));
Rep(i,n+1) {
int sz=SI(e[i]);
if(!sz) continue;
if(sz>=1) {
if(e[i][0]>0) ans+=e[i][0];
if(sz>=2) gmax(ansp,(ll)e[i][1])
}
}
printf("%I64d\n",-ans-ansp);
Rep(i,n+1) e[i].resize(0);
}
return 0;
}
枚举h
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
using namespace std;
#define For(i,n) for(int i=1;i<=n;i++)
#define Fork(i,k,n) for(int i=k;i<=n;i++)
#define ForkD(i,k,n) for(int i=n;i>=k;i--)
#define Rep(i,n) for(int i=0;i
#define ForD(i,n) for(int i=n;i;i--)
#define RepD(i,n) for(int i=n;i>=0;i--)
#define Forp(x) for(int p=pre[x];p;p=next[p])
#define Forpiter(x) for(int &p=iter[x];p;p=next[p])
#define Lson (o<<1)
#define Rson ((o<<1)+1)
#define MEM(a) memset(a,0,sizeof(a));
#define MEMI(a) memset(a,0x3f,sizeof(a));
#define MEMi(a) memset(a,128,sizeof(a));
#define MEMx(a,b) memset(a,b,sizeof(a));
#define INF (0x3f3f3f3f)
#define F (1000000007)
#define pb push_back
#define mp make_pair
#define fi first
#define se second
#define vi vector
#define pi pair
#define SI(a) ((a).size())
#define Pr(kcase,ans) printf("Case #%d: %lld\n",kcase,ans);
#define PRi(a,n) For(i,n-1) cout<
#define PRi2D(a,n,m) For(i,n) { \
For(j,m-1) cout<' ';\
cout<m ]<#pragma comment(linker, "/STACK:102400000,102400000")
#define ALL(x) (x).begin(),(x).end()
#define gmax(a,b) a=max(a,b);
#define gmin(a,b) a=min(a,b);
typedef long long ll;
typedef long double ld;
typedef unsigned long long ull;
ll mul(ll a,ll b){return (a*b)%F;}
ll add(ll a,ll b){return (a+b)%F;}
ll sub(ll a,ll b){return ((a-b)%F+F)%F;}
void upd(ll &a,ll b){a=(a%F+b%F)%F;}
inline int read()
{
int x=0,f=1; char ch=getchar();
while(!isdigit(ch)) {if (ch=='-') f=-1; ch=getchar();}
while(isdigit(ch)) { x=x*10+ch-'0'; ch=getchar();}
return x*f;
}
#define MAXN (22345)
int T;
ll inj[MAXN],jie[MAXN],inv[MAXN];
void pre(int n) {
jie[0]=1;For(i,n) jie[i]=mul(jie[i-1],i);
inj[0]=inj[1]=1;Fork(i,2,n) inj[i]=(F-(F/i))*inj[F%i]%F;
Rep(i,n+1) inv[i]=inj[i];
For(i,n) inj[i]=mul(inj[i],inj[i-1]);
}
int l[MAXN],r[MAXN];
int main()
{
// freopen("b.in","r",stdin);
// freopen(".out","w",stdout);
int T=read();
pre(20000);
while(T--) {
int n=read();
For(i,n) l[i]=read(),r[i]=read();
int minh=*max_element(l+1,l+1+n);
int maxh=*max_element(r+1,r+1+n);
ll ind=1;
For(i,n) ind=ind*inv[r[i]-l[i]+1]%F;
ll ans=0;
Fork(h,minh,maxh) {
ll p1=1,p2=1;
For(i,n){
int tl=l[i],tr=min(h,r[i]);
int pl=h-tl+1,pr=h-tr+1;
int dis=pl-pr+1;
ll t=(pl+pr)*(ll)dis/2;
p1=p1*t%F;
tl=l[i],tr=min(h-1,r[i]);
if(tl>tr) {
p2=0;//continue;
}
pl=h-tl+1,pr=h-tr+1;
dis=pl-pr+1;
t=(pl+pr)*(ll)dis/2;
p2=p2*t%F;
}
p1=sub(p1,p2);
upd(ans,p1);
}
cout<*ind%F<return 0;
}
考虑每个联通块,拆位计算
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
using namespace std;
#define For(i,n) for(int i=1;i<=n;i++)
#define Fork(i,k,n) for(int i=k;i<=n;i++)
#define ForkD(i,k,n) for(int i=n;i>=k;i--)
#define Rep(i,n) for(int i=0;i
#define ForD(i,n) for(int i=n;i;i--)
#define RepD(i,n) for(int i=n;i>=0;i--)
#define Forp(x) for(int p=pre[x];p;p=next[p])
#define Forpiter(x) for(int &p=iter[x];p;p=next[p])
#define Lson (o<<1)
#define Rson ((o<<1)+1)
#define MEM(a) memset(a,0,sizeof(a));
#define MEMI(a) memset(a,0x3f,sizeof(a));
#define MEMi(a) memset(a,128,sizeof(a));
#define MEMx(a,b) memset(a,b,sizeof(a));
#define INF (0x3f3f3f3f)
#define F (1000000007)
#define pb push_back
#define mp make_pair
#define fi first
#define se second
#define vi vector
#define pi pair
#define SI(a) ((a).size())
#define Pr(kcase,ans) printf("Case #%d: %lld\n",kcase,ans);
#define PRi(a,n) For(i,n-1) cout<
#define PRi2D(a,n,m) For(i,n) { \
For(j,m-1) cout<' ';\
cout<#pragma comment(linker, "/STACK:102400000,102400000")
#define ALL(x) (x).begin(),(x).end()
#define gmax(a,b) a=max(a,b);
#define gmin(a,b) a=min(a,b);
typedef long long ll;
typedef long double ld;
typedef unsigned long long ull;
ll mul(ll a,ll b){return (a*b)%F;}
ll add(ll a,ll b){return (a+b)%F;}
ll sub(ll a,ll b){return ((a-b)%F+F)%F;}
void upd(ll &a,ll b){a=(a%F+b%F)%F;}
inline int read()
{
int x=0,f=1; char ch=getchar();
while(!isdigit(ch)) {if (ch=='-') f=-1; ch=getchar();}
while(isdigit(ch)) { x=x*10+ch-'0'; ch=getchar();}
return x*f;
}
#define MAXN (101010)
int T;
class bingchaji
{
public:
int father[MAXN],n,cnt;
void mem(int _n)
{
n=_n;
For(i,n) father[i]=i;
}
int getfather(int x)
{
if (father[x]==x) return x;
return father[x]=getfather(father[x]);
}
void unite(int x,int y)
{
x=getfather(x);
y=getfather(y);
if (x^y) {
father[x]=y;
}
}
bool same(int x,int y)
{
return getfather(x)==getfather(y);
}
}S;
ll v[MAXN],pow_2[MAXN];
vi G[MAXN];
bool cmp(int x,int y) {
return v[x]0;
void work(int i) {
vi vec;
for(int t:G[i]) vec.pb(t);
sort(vec.begin(),vec.end(),cmp);
vector tmp;
for (ll i=0;i<32;++i) {
tmp.clear();
int sz=SI(vec);
Rep(j,sz)
if ((v[vec[j]]>>i)&1)
tmp.push_back(v[vec[j]]);
int tz=SI(tmp);
for (int j=1;jint main()
{
// freopen("cc.in.cpp","r",stdin);
// freopen(".out","w",stdout);
int T=read();
pow_2[0]=1;
For(i,10000)
pow_2[i]=pow_2[i-1]*2ll%F;
while(T--) {
int n=read(),m=read();
S.mem(n+1);
For(i,n) v[i]=read();
For(i,m) {
int x=read(),y=read();
S.unite(x,y);
}
For(i,n) S.father[i]=S.getfather(i);
For(i,n) {
G[S.father[i]].pb(i);
}
res=0;
For(i,n) if(SI(G[i])) {
work(i);
}
printf("%I64d\n",res);
For(i,n) G[i].clear();
}
return 0;
}
显然1个5元对(a[i]=b[j]=c[k]=d[l]=e[m])出现的期望对数是O(n),因此可以暴力解决
注意虽然是期望O(n)但是实际可能大于n对
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
using namespace std;
#define For(i,n) for(int i=1;i<=n;i++)
#define Fork(i,k,n) for(int i=k;i<=n;i++)
#define ForkD(i,k,n) for(int i=n;i>=k;i--)
#define Rep(i,n) for(int i=0;i
#define ForD(i,n) for(int i=n;i;i--)
#define RepD(i,n) for(int i=n;i>=0;i--)
#define Forp(x) for(int p=pre[x];p;p=next[p])
#define Forpiter(x) for(int &p=iter[x];p;p=next[p])
#define Lson (o<<1)
#define Rson ((o<<1)+1)
#define MEM(a) memset(a,0,sizeof(a));
#define MEMI(a) memset(a,0x3f,sizeof(a));
#define MEMi(a) memset(a,128,sizeof(a));
#define MEMx(a,b) memset(a,b,sizeof(a));
#define INF (0x3f3f3f3f)
#define F (1000000007)
#define pb push_back
#define mp make_pair
#define fi first
#define se second
#define vi vector
#define pi pair
#define SI(a) ((a).size())
#define Pr(kcase,ans) printf("Case #%d: %lld\n",kcase,ans);
#define PRi(a,n) For(i,n-1) cout<
#define PRi2D(a,n,m) For(i,n) { \
For(j,m-1) cout<' ';\
cout<#pragma comment(linker, "/STACK:102400000,102400000")
#define ALL(x) (x).begin(),(x).end()
#define gmax(a,b) a=max(a,b);
#define gmin(a,b) a=min(a,b);
typedef long long ll;
typedef long double ld;
typedef unsigned long long ull;
ll mul(ll a,ll b){return (a*b)%F;}
ll add(ll a,ll b){return (a+b)%F;}
ll sub(ll a,ll b){return ((a-b)%F+F)%F;}
void upd(ll &a,ll b){a=(a%F+b%F)%F;}
inline int read()
{
int x=0,f=1; char ch=getchar();
while(!isdigit(ch)) {if (ch=='-') f=-1; ch=getchar();}
while(isdigit(ch)) { x=x*10+ch-'0'; ch=getchar();}
return x*f;
}
#define MAXN (1010)
#define MAXM (666666)
int T;
int a[10][MAXN];
vi v[10][MAXN];
int st[10];
int tot=0,n,k,f[MAXM][10];
int id[MAXM];
bool cmp(int i,int j) {
return f[i][1]1];
}
void dfs(int i,int l) {
if(l>k) {
++tot;
For(t,k) f[tot][t]=st[t];
return ;
}
for(int j:v[l][i]) {
st[l]=j;
dfs(i,l+1);
}
}
bool les(int i,int j) {//i
For(l,k) {
if(f[i][l]>=f[j][l]) return 0;
}return 1;
}
ll g[MAXM];
int main()
{
// freopen("d.in","r",stdin);
// freopen(".out","w",stdout);
int T=read();
while(T--) {
k=read(),n=read();
For(i,k) For(j,n) a[i][j]=read();
For(i,k) {
For(j,n) v[i][a[i][j]].pb(j);
}
tot=0;
For(i,n) {
dfs(i,1);
}
For(i,tot) id[i]=i;
sort(id+1,id+1+tot,cmp);
ll res=0;
For(i,tot) {
g[i]=1;
For(j,i-1) if (les(id[j],id[i])) {
upd(g[i],g[j]);
}
upd(res,g[i]);
}
cout<0 );
}
return 0;
}
随机对图重染色若干次,然后bfs。
注意随机次数必须足够多。