20200627 多校難題訓練二

2020 Petrozavodsk Winter Camp, Jagiellonian U Contest

G. Invited Speakers

給出 nn 張桌子和 nn 個人的座標,將其一一配對,配對可以用一些線段連接,線段不能交叉。求方案。
所有點橫縱座標都不一樣。

設一個大常數 CC,先將桌子和人分別按照橫座標排序,然後這樣構造:
在這裏插入圖片描述
(ax,ay)(ax,C+i)(C+i,C+i)(C+i,Ci)(bx,Ci)(bx,by)(a_x,a_y)\to (a_x,C+i)\to(C+i,C+i)\to(C+i,C-i)\to(b_x,C-i)\to(b_x,b_y)

Code:

#include<bits/stdc++.h>
#define maxn 15
using namespace std;
int n,C;
pair<int,int>a[maxn],b[maxn];
#define x first
#define y second
int main()
{
	int T;
	for(scanf("%d",&T);T--;){
		scanf("%d",&n),C=0;
		for(int i=1;i<=n;i++) scanf("%d%d",&a[i].x,&a[i].y),C=max(C,max(abs(a[i].x),abs(a[i].y)));
		for(int i=1;i<=n;i++) scanf("%d%d",&b[i].x,&b[i].y),C=max(C,max(abs(b[i].x),abs(b[i].y)));
		sort(a+1,a+1+n),sort(b+1,b+1+n);
		for(int i=1;i<=n;i++){
			int X=C+n-i+1;
			printf("%d\n%d %d\n%d %d\n%d %d\n%d %d\n%d %d\n%d %d\n",
			6,a[i].x,a[i].y,a[i].x,X,X,X,X,-X,b[i].x,-X,b[i].x,b[i].y);
		}
	}
}

I. Sum of Palindromes

把一個長度爲 n105n\le10^5 的數字串分解爲 25\le25 個迴文數之和。

每次取前一半,末位-1,然後翻轉對應到後一半,然後相減,每次長度減少一半,只需要 logn\log n 次。
有一些特判,比如 -1 之後位數減少的情況,以及最後剩下 “10”。

Code:

#include<bits/stdc++.h>
#define maxn 100005
#define pb(x) push_back(x)
using namespace std;
int n;
char a[maxn],b[maxn];
vector<string>ans;
int main()
{
	int T;
	for(scanf("%d",&T);T--;){
		scanf("%s",a),n=strlen(a);
		ans.clear();
		for(reverse(a,a+n);n;){
			if(n==2&&a[1]=='1'&&a[0]=='0') {ans.pb("1"),ans.pb("9");break;}
			if(n==1) {ans.pb(string(1,a[0]));break;}
			int l=n/2;
			for(int i=n-1;i>=l;i--) b[i]=a[i];
			b[l]--;
			for(int i=l;b[i]<'0';i++) b[i]+=10,b[i+1]--;
			if(b[n-1]=='0'){
				for(int i=0;i<l;i++) b[i]=b[n-2-i];
				if(!(n&1)) b[l-1]='9';
				ans.push_back(string(b,b+n-1));
			}
			else{
				for(int i=0;i<l;i++) b[i]=b[n-1-i];
				ans.push_back(string(b,b+n));
			}
			for(int i=0;i<n;i++) if((a[i]-=b[i]-'0')<'0') a[i]+=10,a[i+1]--;
			while(n&&a[n-1]=='0') n--;
		}
		printf("%d\n",ans.size());
		for(int i=0,lim=ans.size();i<lim;i++) printf("%s\n",ans[i].c_str());
	}
}

H. Lighthouses

凸多邊形,有座標,一些頂點之間的邊,求最長的邊不交叉的路徑的長度。

因爲是凸包,所以向某一邊走後不可能再走向另外一邊,區間DP,記 ffgg 分別表示走左還是走右即可。枚舉到達點轉移,O(n3)O(n^3)

Code:

#include<bits/stdc++.h>
#define maxn 305
using namespace std;
int n,m,X[maxn],Y[maxn];
bool e[maxn][maxn];
double ans,f[maxn][maxn],g[maxn][maxn],dis[maxn][maxn];
double Dist(int i,int j){return sqrt(1ll*(X[i]-X[j])*(X[i]-X[j])+1ll*(Y[i]-Y[j])*(Y[i]-Y[j]));}
int main()
{
	int T;
	for(scanf("%d",&T);T--;){
		scanf("%d",&n);
		for(int i=0;i<n;i++) scanf("%d%d",&X[i],&Y[i]);
		for(int i=0;i<n;i++) for(int j=0;j<n;j++) e[i][j]=0,dis[i][j]=Dist(i,j),f[i][j]=g[i][j]=0;
		scanf("%d",&m);
		for(int i=1,x,y;i<=m;i++) scanf("%d%d",&x,&y),x--,y--,e[x][y]=e[y][x]=1;
		ans=0;
		for(int d=2;d<n;d++)
			for(int l=0;l<n;l++){
				int r=(l+d)%n;
				for(int k=(l+1)%n;k!=r;k=(k+1)%n){
					double x=max(f[l][k],g[r][k]);
					if(e[r][k]) f[l][r]=max(f[l][r],dis[r][k]+x);
					if(e[l][k]) g[r][l]=max(g[r][l],dis[l][k]+x);
				}
			}
		for(int l=0;l<n;l++) for(int r=0;r<n;r++) if(l!=r&&e[l][r])
			ans=max(ans,dis[l][r]+max(f[l][r],g[l][r]));
		printf("%.9f\n",ans);
	}
}

A. Bags of Candies

一組可以包含兩個不互質的數 或 一個單獨的數,求將1到n最少分多少組。n1011n\le10^{11}

答案顯然爲 nn-最多配對數
n2<pn\frac n2<p\le n 的質數 pp 的數量爲 D(n)D(n),那麼 D(n)D(n) 以及 1 都只能分成單獨的組,配對數的上界爲 nD(n)12\lfloor\frac {n-D(n)-1}2\rfloor

構造上界:
將剩下的數按照最大質因子分組,同一組的顯然可以配對,如果組的大小爲奇數那麼會剩下一個數,對於最大質因子爲 xn2x\le \frac n2 的組,2x2x 一定在這個組中,那麼把讓剩下的數爲 2x2x,最後剩下的數都含有 22 這個因子,繼續配對即可達到上界。

於是就是求區間質數,官方題解用的是分段打表,剩下的一段用埃氏篩 O((rl)loglog(rl))O((r-l)\log\log (r-l))
我直接 Min_25 了,語言選 GNU G++17 9.2.0 (64 bit, msys 2) 才能過。。其它的會 T。。
開 O2 的話除法用浮點數乘法會快很多(3倍)。

Code:

#include<bits/stdc++.h>
#define maxn 1000005
#define LL long long
using namespace std;
int sn,m;
LL n,a[maxn],s[maxn];
inline int ID(LL x){return x<=sn?x:m-n/x+1;}
int main()
{
	int T;
	for(scanf("%d",&T);T--;){
		scanf("%lld",&n),sn=sqrt(n),m=0;
		for(LL i=1;i<=n;i++) a[++m]=i=n/(n/i),s[m]=i-1;
		for(int i=2;i<=sn;i++) if(s[i]^s[i-1]){
			double inv=1.0/i;
			LL lim=1ll*i*i,sp=s[i-1];
			for(int j=m;a[j]>=lim;j--)
				s[j]-=s[ID((LL)(a[j]*inv+1e-9))]-sp;
		}
		printf("%lld\n",n-(n-(s[m]-s[ID(n/2)])-1)/2);
	}
}

E. Contamination

平面直角座標系,給出 nn 個圓,qq 次詢問,(px,py)(qx,qy)(px,py)\to(qx,qy) 在縱座標[ymin,ymax][y_{min},y_{max}]的範圍內是否存在一條不經過圓的路徑(可以走實數)。 n,q106n,q\le10^6,圓不相交。

因爲圓不相交所以只可能是一個圓連通了上下邊界,稍作分析相當於是問是否存在一個圓 (x,y,r)(x,y,r) 滿足 min(px,qx)xmax(px,qx)\min(px,qx)\le x\le \max(px,qx)yryminymaxc+ry-r\le y_{min}\le y_{max}\le c+r
乍一看是個三維數點,但是這並不是個計數問題而是存在性問題,所以第三維的“數”可以變成求最值。

具體地說,按 yy 從下到上掃描線,遇到 yry-r 就在線段樹的 xx 位置加入 y+ry+r,在 yminy_{min} 處遇到詢問就查詢線段樹上 [min(px,qx),max(px,qx)][\min(px,qx),\max(px,qx)] 的最大值是否大於等於 ymaxy_{max} 即可。

Code:

#include<bits/stdc++.h>
#define maxn 1000005
#define maxp maxn*22
using namespace std;
const int inf = 1e9;
int n,m,px[maxn],qx[maxn],cnt;
bool ans[maxn];
struct node{
	int y,my,x,id;
	bool operator < (const node &p)const{return y==p.y?id<p.id:y<p.y;}
}q[maxn<<1];
int rt,lc[maxp],rc[maxp],mx[maxp],sz;
void ins(int &i,int l,int r,int x,int v){
	if(!i) i=++sz,mx[i]=-inf-1;
	mx[i]=max(mx[i],v);
	if(l==r) return;
	int mid=(l+r)>>1;
	x<=mid?ins(lc[i],l,mid,x,v):ins(rc[i],mid+1,r,x,v);
}
int qry(int i,int l,int r,int x,int y){
	if(!i) return -inf-1;
	if(x<=l&&r<=y) return mx[i];
	int mid=(l+r)>>1,ret=-inf-1;
	if(x<=mid) ret=qry(lc[i],l,mid,x,y);
	if(y>mid) ret=max(ret,qry(rc[i],mid+1,r,x,y));
	return ret;
}
int main()
{
	scanf("%d%d",&n,&m);
	for(int i=1,x,y,r;i<=n;i++) scanf("%d%d%d",&x,&y,&r),q[++cnt]=(node){y-r,y+r,x,0};
	for(int i=1;i<=m;i++) ++cnt,scanf("%d%*d%d%*d%d%d",&px[i],&qx[i],&q[cnt].y,&q[cnt].my),q[cnt].id=i;
	sort(q+1,q+1+cnt);
	for(int i=1;i<=cnt;i++)
		if(!q[i].id) ins(rt,-inf,inf,q[i].x,q[i].my);
		else {int l=px[q[i].id],r=qx[q[i].id]; ans[q[i].id]=qry(rt,-inf,inf,min(l,r),max(l,r))<q[i].my;}
	for(int i=1;i<=m;i++) puts(ans[i]?"YES":"NO");
}

F. The Halfwitters

一個 1n1\sim n 的排列,用 aa 的代價交換相鄰數字,bb 的代價翻轉整個排列,cc 的代價變爲隨機排列,問將排列變爲 1,2,...,n1,2,...,n 的最小期望代價。

aa 操作可以增加或減少一個逆序對,bb 操作將逆序對數 kk 變爲 n(n1)2k\frac {n(n-1)}2-k
假設不用 cc,那麼有 kk 個逆序對的最小代價爲 fk=min(ak,b+a(n(n1)2k))f_k=\min(ak,b+a(\frac {n(n-1)}2-k))
設隨機排列的期望代價爲 XX,那麼真實答案 gk=min(X+c,fk)g_k=\min(X+c,f_k),有 X=1n!gkcntkX=\frac 1{n!}\sum g_k*cnt_k
要代價儘量小,那麼顯然 XX 越小越優,那麼剩下就是找到 XX 的最小可能值。
ff 排序得到 hh,那麼肯定是前一部分選 ff,後一部分選 X+cX+c,枚舉位置 ii,那麼有:
Xn!=j=1ihjcntid[j]+(X+c)j=i+1ncntid[j]X*n! = \sum_{j=1}^ih_j*cnt_{id[j]}+(X+c)*\sum_{j=i+1}^ncnt_{id[j]}
解出 XX,如果滿足 X+chi+1X+c\le h_{i+1},那麼這個 XX 就是合法的,取最小即可。實際上位置 ii 滿足單調性,可以二分。可以嘗試作差比較證明。

Code:

#include<bits/stdc++.h>
#define maxn 155
#define LL long long
using namespace std;
int n,id[maxn],p[maxn];
LL cnt[18][maxn],fac[18],f[maxn];
bool cmp(int i,int j){return f[i]<f[j];}
int main()
{
	int T,a,b,c,d;
	cnt[0][0]=fac[0]=1;
	for(int i=1;i<=16;i++) for(int j=0;j<=i*(i-1)/2;j++) 
		for(int k=0;k<=min(i-1,j);k++) cnt[i][j]+=cnt[i-1][j-k];
	for(int i=1;i<=16;i++) fac[i]=fac[i-1]*i;
	for(scanf("%d",&T);T--;){
		scanf("%d%d%d%d%d",&n,&a,&b,&c,&d);
		int N = n*(n-1)/2;
		for(int i=0;i<=N;i++) f[i]=min(a*i,b+a*(N-i)),id[i]=i;
		sort(id,id+N+1,cmp);
		LL pre=0,suf=fac[n],fz,fm;
		double X = 1e20;
		for(int o=0;o<N;o++){
			int i=id[o];
			pre+=f[i]*cnt[n][i],suf-=cnt[n][i];
			fm=fac[n]-suf,fz=pre+c*suf;
			double x = 1.0*fz/fm;
			if(x+c<=f[id[o+1]]) {X=x;break;}
		}
		fz+=c*fm; LL D=__gcd(fz,fm); fz/=D,fm/=D;
		while(d--){
			for(int i=1;i<=n;i++) scanf("%d",&p[i]);
			int k=0;
			for(int i=1;i<n;i++) for(int j=i+1;j<=n;j++) if(p[i]>p[j]) k++;
			if(f[k]<=X+c) printf("%lld/1\n",f[k]);
			else printf("%lld/%lld\n",fz,fm);
		}
	}
}

J. Space Gophers

N=106N=10^6NNNN*N*N的立方體小格,給出 nn 條形如 (x,y,1)(x,y,-1) 的隧道,表示 z,(x,y,z)\forall z,(x,y,z) 爲空。(x,1,z),(1,y,z)(x,-1,z),(-1,y,z) 同理,兩個空格子有公共面視爲連通,給 qq 次詢問 (a1,b1,c1)(a_1,b_1,c_1)(a2,b2,c2)(a_2,b_2,c_2) 是否連通。n3105,q5105n\le3*10^5,q\le5*10^5

把隧道看做點。
對於形如 (x,y,1)(x,y,-1) 的點,有兩種情況連通:

  • 1-1 的位置相同, (x,y)(x,y)周圍四連通的點與其連通。
  • 1-1 的位置不同,兩個點都不爲 1-1 的位置相差 1\le1

連通用並查集維護。
查找第一種點用 map<pair<int,int>,int>A[3]map<pair<int,int>,int>A[3] 解決。
查找第二種點用 vector<int>B[i][j][x]vector<int>B[i][j][x],表示1-1的位置爲iixx的位置爲jj,座標爲xx的點。如果一個點向某個 vectorvector 有連邊,那麼整個 vectorvector 都連通了,刪去除第一個元素外的元素沒有影響。
這樣複雜度就是 O((n+q)logn)O((n+q)\log n) 的。常數很大,我加了fread才過。。

Code:

#include<bits/stdc++.h>
#define maxn 300005
using namespace std;
char cb[1<<20],*cs,*ct;
#define getc() (cs==ct&&(ct=(cs=cb)+fread(cb,1,1<<20,stdin),cs==ct)?0:*cs++)
void read(int &a){
	char c;bool f=0;while(!isdigit(c=getc())) c=='-'&&(f=1);
	for(a=c-'0';isdigit(c=getc());a=a*10+c-'0'); f&&(a=-a);
}
int n,f[maxn],d[4][2]={{0,1},{0,-1},{1,0},{-1,0}};
map<pair<int,int>,int>A[3];
vector<int>B[3][3][1000005];
int find(int x){return f[x]==x?x:f[x]=find(f[x]);}
void join(int x,int y){if(!y) return; f[find(x)]=find(y);}
void links(int x,vector<int>&y){
	if(!y.empty()){
		for(;y.size()>1;y.pop_back()) join(x,y.back());
		join(x,y.back());
	}
}
int get(int *a){
	for(int i=0,id;i<3;i++) if(id=A[i][make_pair(a[(i+1)%3],a[(i+2)%3])]) return find(id);
}
int main()
{
	int T,Q;
	for(scanf("%d",&T);T--;){
		read(n);
		for(int i=1;i<=n;i++) f[i]=i;
		for(int i=0;i<3;i++){
			A[i].clear();
			for(int j=0;j<3;j++) if(i!=j) for(int k=1;k<=1000000;k++) B[i][j][k].clear();
		}
		for(int id=1;id<=n;id++){
			int a[3]; read(a[0]),read(a[1]),read(a[2]);
			for(int i=0;i<3;i++) if(a[i]==-1){
				int x=a[(i+1)%3],y=a[(i+2)%3];
				for(int j=0;j<4;j++) join(id,A[i][make_pair(x+d[j][0],y+d[j][1])]);
				for(int j=-1;j<=1;j++) links(id,B[(i+2)%3][(i+1)%3][x+j]),links(id,B[(i+1)%3][(i+2)%3][y+j]);
				A[i][make_pair(x,y)]=id;
				B[i][(i+1)%3][x].push_back(id),B[i][(i+2)%3][y].push_back(id);
			}
		}
		read(Q);
		for(int a[3],b[3];Q--;){
			read(a[0]),read(a[1]),read(a[2]),read(b[0]),read(b[1]),read(b[2]);
			puts(get(a)==get(b)?"YES":"NO");
		}
	}
}

2018 Petrozavodsk Winter Camp, Yandex Cup

I. \leq or \geq

交互題。
nn 個棧排成一排,大小都爲 kk,不知道棧中元素,每輪給出棧頂,你給出一個數 xx,然後交互庫給出一個符號R=R= \le\ge,棧頂 R xR ~x 的元素被彈出,進入下一輪,直到全棧爲空。要求在50次內將棧清空。n104,k10n\le10^4,k\le10

記每個棧的大小爲 szisz_i,每個棧的權值爲 pszip^{sz_i}pp 是設定的一個常數,記 S=psziS=\sum p^{sz_i}
注意到必然存在一個位置 ii,使得左半部分和右半部分(均包含ii)的和都 12\ge \frac 12
所以將棧按照棧頂元素從小到大排序,然後找到位置 ii,並令 xx 等於這個棧的棧頂。那麼無論給出的符號是小於等於還是大於等於,新的 SS 必然 S2+S21p=(12+12p)S\le\frac S2+\frac S2*\frac 1p=(\frac 12+\frac 1{2p})S
顯然 pp 越大 SS 每次縮得越小,然而當 p=3p=3 時爲 23S\frac 23S,而 log2310422.7\log_{\frac 23}10^{-4}\approx22.7,已經足夠在 50 次內完成。

Code:

#include<bits/stdc++.h>
#define maxn 10005
using namespace std;
int n,k,siz[maxn],pw[12],id[maxn],a[maxn];
bool cmp(int i,int j){return a[i]<a[j];}
int main()
{
	scanf("%d%d",&n,&k);
	for(int i=(pw[1]=3,2);i<=10;i++) pw[i]=pw[i-1]*3;
	for(int i=1;i<=n;i++) siz[i]=k;
	while(1){
		for(int i=1;i<=n;i++) scanf("%d",&a[i]),id[i]=i;
		sort(id+1,id+1+n,cmp);
		int sum=0;
		for(int i=1;i<=n;i++) sum+=pw[siz[i]];
		int x=0;
		for(int i=1;i<=n;i++)
			if((x+=pw[siz[id[i]]])*2>=sum){
				printf("%d\n",x=a[id[i]]); fflush(stdout);
				break;
			}
		char op[4]; scanf("%s",op);
		if(op[0]=='E') return 0;
		if(op[0]=='<') {for(int i=1;i<=n;i++) if(siz[i]&&a[i]<=x) siz[i]--;}
		else {for(int i=1;i<=n;i++) if(siz[i]&&a[i]>=x) siz[i]--;}
	}
}

J. Stairways

11nn 從左到右排成一排,每個人有權值 tit_i,將其分成兩排,排內保持原來的順序,如果對前後兩個人 x,yx,ytx>tyt_x>t_y,則要付出 txtyt_x-t_y 的代價,並使 ty=txt_y=t_x,求最小代價。
n105,t109n\le10^5,t\le10^9

每個人的代價相當於是前綴最大值 preipre_i 減去 tit_i
在兩排的前綴最大值確定的情況下後面的最優解就確定了,所以設 f[i][j]f[i][j] 表示前 i1i-1 個數,第一排的前綴最大值爲 prei1pre_{i-1},第二排的前綴最大值爲 jj 時,後 [i,n][i,n] 放進去的最小代價。

考慮 ii 放進第一排還是第二排以及 jjtit_i 的大小關係進行轉移。

  • jtij\ge t_iii 放進第二排最優,f[i][j]f[i+1][j]+jtif[i][j]\larr f[i+1][j]+j-t_i
  • j<tij<t_iii 放進第二排有:f[i][j]f[i+1][ti]f[i][j]\larr f[i+1][t_i]
                 i\ \ \ \ \ \ \ \ \ \ \ \ \ i 放進第一排有:f[i][j]f[i+1][j]+preitif[i][j]\larr f[i+1][j]+pre_i-t_i

可能會有 j>prei1j>pre_{i-1} 的狀態,但是這並不影響答案,最優解一定可以遞推出來。
第一種操作是區間加等差數列,第二種操作是區間加然後對一個數 chkminchkmin
觀察可以發現對固定的 iif[i][j]f[i][j]jj 增大單調不降,所以第二種操作可以二分出前一部分取 f[i+1][j]+preitif[i+1][j]+pre_i-t_i,後一部分取 f[i+1][ti]f[i+1][t_i] 的位置,然後區間加、區間賦值即可。
查詢需要單點查詢,以及線段樹二分。

線段樹維護出區間左端點的值,區間加標記的首項公差,區間賦值標記即可。可以離散化。

Code:

#include<bits/stdc++.h>
#define maxn 100005
#define LL long long
using namespace std;
int n,N,a[maxn],A[maxn],pre[maxn];
LL tag[maxn<<2];
struct data{
	LL x,d,v; data(LL x=0,LL d=0,LL v=0):x(x),d(d),v(v){}
	void operator += (const data &t){x+=t.x,d+=t.d,v+=t.x;}
}t[maxn<<2];
#define lc i<<1
#define rc i<<1|1
void down(int i,int L,int M){
	if(~tag[i]) t[lc]=t[rc]=data(0,0,tag[i]),tag[lc]=tag[rc]=tag[i],tag[i]=-1;
	if(t[i].x||t[i].d) t[lc]+=t[i],t[rc]+=data(t[i].x+(A[M+1]-A[L])*t[i].d,t[i].d),t[i].x=t[i].d=0;
}
void Add(int i,int l,int r,int x,int y,data v){
	if(x<=l&&r<=y) return t[i]+=data(v.x+(A[l]-A[x])*v.d,v.d);
	int mid=(l+r)>>1; down(i,l,mid);
	if(x<=mid) Add(lc,l,mid,x,y,v);
	if(y>mid) Add(rc,mid+1,r,x,y,v);
	t[i].v=t[lc].v;
}
void Cov(int i,int l,int r,int x,int y,LL v){
	if(x<=l&&r<=y) {t[i]=data(0,0,v),tag[i]=v;return;}
	int mid=(l+r)>>1; down(i,l,mid);
	if(x<=mid) Cov(lc,l,mid,x,y,v);
	if(y>mid) Cov(rc,mid+1,r,x,y,v);
	t[i].v=t[lc].v;
}
int find(int i,int l,int r,LL x){
	if(l==r) return t[i].v<=x?l:l-1;
	int mid=(l+r)>>1; down(i,l,mid);
	return t[rc].v<=x?find(rc,mid+1,r,x):find(lc,l,mid,x);
}
LL qry(int i,int l,int r,int x){
	if(l==r) return t[i].v;
	int mid=(l+r)>>1; down(i,l,mid);
	return x<=mid?qry(lc,l,mid,x):qry(rc,mid+1,r,x);
}
int main()
{
	scanf("%d",&n);
	for(int i=1;i<=n;i++) scanf("%d",&a[i]),A[i]=a[i];
	sort(A+1,A+1+n),N=unique(A+1,A+1+n)-A-1;
	for(int i=1;i<=n;i++) a[i]=lower_bound(A+1,A+1+N,a[i])-A,pre[i]=max(pre[i-1],a[i]);
	memset(tag,-1,sizeof tag);
	for(int i=n;i>=1;i--){
		LL now=qry(1,1,N,a[i]);
		int p=min(a[i]-1,find(1,1,N,now-(A[pre[i]]-A[a[i]])));
		if(p) Add(1,1,N,1,p,data(A[pre[i]]-A[a[i]],0));
		if(p<a[i]-1) Cov(1,1,N,p+1,a[i]-1,now);
		Add(1,1,N,a[i],N,data(0,1));
	}
	printf("%lld\n",qry(1,1,N,1));
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章