zoukankan      html  css  js  c++  java
  • Codeforces Round #569 (Div. 1)

    Codeforces Round #569 (Div. 1)

    A Valeriy and Deque

    考虑先走n-1步,那么走完了n-1步后最大的数一定就在最前面了,接下来的操作会让后面的n-1个数进入循环,那么对于一个询问(m_i),如果(m_i<n-1),那么直接回答即可,否则将(m_i)对n-1取模,然后回答。

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<queue>
    #include<cctype>
    #define qmin(x,y) (x=min(x,y))
    #define qmax(x,y) (x=max(x,y))
    #define vic vector<int>
    #define vit vic::iterator
    #define pir pair<int,int>
    #define fr first
    #define sc second
    #define mp(x,y) make_pair(x,y)
    #define rsort(x,y) sort(x,y),reverse(x,y)
    using namespace std;
    
    inline char gc() {
    //	static char buf[100000],*p1,*p2;
    //	return (p1==p2)&&(p2=(p1=buf)+fread(buf,1,100000,stdin),p1==p2)?EOF:*p1++;
    	return getchar();
    }
    
    template<class T>
    int read(T &ans) {
    	ans=0;char ch=gc();T f=1;
    	while(!isdigit(ch)) {
    		if(ch==EOF) return -1;
    		if(ch=='-') f=-1;
    		ch=gc();
    	}
    	while(isdigit(ch))
    		ans=ans*10+ch-'0',ch=gc();
    	ans*=f;return 1;
    }
    
    template<class T1,class T2>
    int read(T1 &a,T2 &b) {
    	return read(a)!=EOF&&read(b)!=EOF?2:EOF;
    }
    
    template<class T1,class T2,class T3>
    int read(T1 &a,T2 &b,T3 &c) {
    	return read(a,b)!=EOF&&read(c)!=EOF?3:EOF;
    }
    
    typedef long long ll;
    const int Maxn=1100000;
    const int inf=0x3f3f3f3f;
    
    int n,t,a[Maxn],c[Maxn];
    ll x;
    pir b[Maxn];
    
    signed main() {
    //	freopen("test.in","r",stdin);
    //	freopen("out","w",stdout);
    	read(n,t);
    	for(int i=1;i<=n;i++) read(a[i]);
    	deque<int> q;
    	for(int i=1;i<=n;i++) q.push_back(a[i]);
    	for(int i=1;i<n;i++) {
    		int x=q.front(); q.pop_front();
    		int y=q.front(); q.pop_front();
    		b[i]=mp(x,y);
    		if(x<y) swap(x,y);
    		q.push_front(x);
    		q.push_back(y);
    	}
    	int mx=q.front(); q.pop_front();
    	for(int i=1;i<n;i++) c[i]=q.front(),q.pop_front();
    	while(t--) {
    		read(x);
    		if(x<n) printf("%d %d
    ",b[x].fr,b[x].sc);
    		else {
    			x-=n;
    			printf("%d %d
    ",mx,c[x%(n-1)+1]);
    		}
    	}
    	return 0;
    }
    

    B Tolik and His Uncle

    构造题。

    ((1,1) ightarrow(n,m) ightarrow(1,2) ightarrow(n,m-1) ightarrowcdots ightarrow(n,1) ightarrow(2,1) ightarrow(n-1,m) ightarrowcdots)

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<queue>
    #include<cctype>
    #define qmin(x,y) (x=min(x,y))
    #define qmax(x,y) (x=max(x,y))
    #define vic vector<int>
    #define vit vic::iterator
    #define pir pair<int,int>
    #define fr first
    #define sc second
    #define mp(x,y) make_pair(x,y)
    #define rsort(x,y) sort(x,y),reverse(x,y)
    using namespace std;
    
    inline char gc() {
    //	static char buf[100000],*p1,*p2;
    //	return (p1==p2)&&(p2=(p1=buf)+fread(buf,1,100000,stdin),p1==p2)?EOF:*p1++;
    	return getchar();
    }
    
    template<class T>
    int read(T &ans) {
    	ans=0;char ch=gc();T f=1;
    	while(!isdigit(ch)) {
    		if(ch==EOF) return -1;
    		if(ch=='-') f=-1;
    		ch=gc();
    	}
    	while(isdigit(ch))
    		ans=ans*10+ch-'0',ch=gc();
    	ans*=f;return 1;
    }
    
    template<class T1,class T2>
    int read(T1 &a,T2 &b) {
    	return read(a)!=EOF&&read(b)!=EOF?2:EOF;
    }
    
    template<class T1,class T2,class T3>
    int read(T1 &a,T2 &b,T3 &c) {
    	return read(a,b)!=EOF&&read(c)!=EOF?3:EOF;
    }
    
    typedef long long ll;
    //const int Maxn=;
    const int inf=0x3f3f3f3f;
    
    int n,m;
    
    void work1(int x,int y) {
    	for(int l=1,r=m;l<=m;l++,r--) printf("%d %d
    %d %d
    ",x,l,y,r);
    }
    
    void work2(int x) {
    	for(int l=1,r=m;l<=r;l++,r--) {
    		if(l!=r) printf("%d %d
    %d %d
    ",x,l,x,r);
    		else printf("%d %d
    ",x,l);
    	}
    }
    
    signed main() {
    //	freopen("test.in","r",stdin);
    	read(n,m);
    	for(int l=1,r=n;l<=r;l++,r--) {
    		if(l!=r) work1(l,r);
    		else work2(l);
    	}
    	return 0;
    }
    

    C Serge and Dining Room

    考虑要求的实际上就是最大的x,满足价格大于x的菜的数目大于钱数大于x的人数。

    那么这个问题就是单点修改,然后查询后缀和,这样很不好搞,于是变成前缀修改,单点查询,然后就可以在线段树上二分了。

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<queue>
    #include<cctype>
    #define qmin(x,y) (x=min(x,y))
    #define qmax(x,y) (x=max(x,y))
    #define vic vector<int>
    #define vit vic::iterator
    #define pir pair<int,int>
    #define fr first
    #define sc second
    #define mp(x,y) make_pair(x,y)
    #define rsort(x,y) sort(x,y),reverse(x,y)
    using namespace std;
    
    inline char gc() {
    //	static char buf[100000],*p1,*p2;
    //	return (p1==p2)&&(p2=(p1=buf)+fread(buf,1,100000,stdin),p1==p2)?EOF:*p1++;
    	return getchar();
    }
    
    template<class T>
    int read(T &ans) {
    	ans=0;char ch=gc();T f=1;
    	while(!isdigit(ch)) {
    		if(ch==EOF) return -1;
    		if(ch=='-') f=-1;
    		ch=gc();
    	}
    	while(isdigit(ch))
    		ans=ans*10+ch-'0',ch=gc();
    	ans*=f;return 1;
    }
    
    template<class T1,class T2>
    int read(T1 &a,T2 &b) {
    	return read(a)!=EOF&&read(b)!=EOF?2:EOF;
    }
    
    template<class T1,class T2,class T3>
    int read(T1 &a,T2 &b,T3 &c) {
    	return read(a,b)!=EOF&&read(c)!=EOF?3:EOF;
    }
    
    typedef long long ll;
    const int Maxn=1100000;
    const int inf=0x3f3f3f3f;
    
    int tl[Maxn<<2],tr[Maxn<<2],tn[Maxn<<2],bj[Maxn<<2];
    int n,m,a[Maxn],b[Maxn],q,opt,x,y;
    
    #define lch (root<<1)
    #define rch (root<<1|1)
    
    void build(int root,int l,int r) {
    	tl[root]=l,tr[root]=r;
    	if(l==r) return ;
    	int mid=l+r>>1;
    	build(lch,l,mid);
    	build(rch,mid+1,r);
    }
    
    inline void update(int root) {
    	tn[root]=max(tn[lch],tn[rch]);
    }
    
    inline void abj(int root,int x) {
    	tn[root]+=x;
    	bj[root]+=x;
    }
    
    void pushdown(int root) {
    	if(bj[root]) {
    		abj(lch,bj[root]);
    		abj(rch,bj[root]);
    		bj[root]=0;
    	}
    }
    
    void chang(int root,int x,int y) {
    	int l=tl[root],r=tr[root],mid=l+r>>1;
    	if(l==r) {
    		tn[root]+=y;
    		return ;
    	}
    	pushdown(root);
    	if(x<=mid) {
    		chang(lch,x,y);
    		update(root);
    		return ;
    	}
    	abj(lch,y);
    	chang(rch,x,y);
    	update(root);
    }
    
    int work(int root) {
    	if(tl[root]==tr[root]) return tl[root];
    	pushdown(root);
    	return work(tn[rch]>=1?rch:lch);
    }
    
    signed main() {
    //	freopen("test.in","r",stdin);
    	read(n,m);
    	build(1,1,1000000);
    	for(int i=1;i<=n;i++) {
    		read(a[i]);
    		chang(1,a[i],1);
    	}
    	for(int i=1;i<=m;i++) {
    		read(b[i]);
    		chang(1,b[i],-1);
    	}
    	read(q);
    	for(int i=1;i<=q;i++) {
    		read(opt,x,y);
    		if(opt==1) {
    			chang(1,a[x],-1);
    			a[x]=y;
    			chang(1,a[x],1);
    		}
    		else {
    			chang(1,b[x],1);
    			b[x]=y;
    			chang(1,b[x],-1);
    		}
    		if(tn[1]>=1) printf("%d
    ",work(1));
    		else puts("-1");
    	}
    	return 0;
    }
    

    D Fedor Runs for President

    考虑加上一条边会增加多少条简单路径,那么把这条边连接的两个点之间的链拎出来,树的形态就变成了一条链上每个点上挂着一颗树,那么答案就等于(n^2-sum_isize[i]^2)。显然选的两个点一定是两个叶子,因为如果不是两个叶子,那么再继续往下走一定会更优。

    考虑枚举选的两个点的lca,设(i)为当前枚举的lca的一个儿子,(f_i)(i)这个子树中叶子到(i)的链上的点除了链上的子树外的点的数目的平方的和的最小值。转移为(f_{root}=min_i {f_i+(size[root]-size[i])^2})

    现在来考虑统计答案,那么对于当前点的两个儿子(i,j),其答案除了(f_i+f_j)外还有当前点的大小之和,即(f_i+f_j+(n-size[i]-size[j])^2),展开一下有(n^2+(f_i+size[i]^2-2cdot ncdot size[i])+(f_j+size[j]^2-2cdot ncdot size[j])+2cdot size[i]cdot size[j]),那么按照(size)排序后用单调栈处理即可。

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<queue>
    #include<cctype>
    #define qmin(x,y) (x=min(x,y))
    #define qmax(x,y) (x=max(x,y))
    #define vic vector<int>
    #define vit vic::iterator
    #define pir pair<int,int>
    #define fr first
    #define sc second
    #define mp(x,y) make_pair(x,y)
    #define rsort(x,y) sort(x,y),reverse(x,y)
    using namespace std;
    
    inline char gc() {
    //	static char buf[100000],*p1,*p2;
    //	return (p1==p2)&&(p2=(p1=buf)+fread(buf,1,100000,stdin),p1==p2)?EOF:*p1++;
    	return getchar();
    }
    
    template<class T>
    int read(T &ans) {
    	ans=0;char ch=gc();T f=1;
    	while(!isdigit(ch)) {
    		if(ch==EOF) return -1;
    		if(ch=='-') f=-1;
    		ch=gc();
    	}
    	while(isdigit(ch))
    		ans=ans*10+ch-'0',ch=gc();
    	ans*=f;return 1;
    }
    
    template<class T1,class T2>
    int read(T1 &a,T2 &b) {
    	return read(a)!=EOF&&read(b)!=EOF?2:EOF;
    }
    
    template<class T1,class T2,class T3>
    int read(T1 &a,T2 &b,T3 &c) {
    	return read(a,b)!=EOF&&read(c)!=EOF?3:EOF;
    }
    
    typedef long long ll;
    const int Maxn=1100000;
    const int inf=0x3f3f3f3f;
    
    int to[Maxn],nxt[Maxn],first[Maxn],tot=1;
    int n,m,u,v,d[Maxn],siz[Maxn];
    ll f[Maxn],res;
    pair<ll,ll> q[Maxn],a[Maxn];
    
    inline void add(int u,int v) {
    	to[tot]=v;
    	nxt[tot]=first[u];
    	first[u]=tot++;
    	to[tot]=u;
    	nxt[tot]=first[v];
    	first[v]=tot++;
    }
    
    inline ll sqr(ll x) {
    	return x*x;
    }
    
    ll cal(pair<ll,ll> x,ll y) {
    	return y*x.fr+x.sc;
    }
    
    void work(int root,int fa) {
    	siz[root]=1,f[root]=1ll*n*n;
    	for(int i=first[root];i;i=nxt[i])
    		if(to[i]!=fa) work(to[i],root),siz[root]+=siz[to[i]];
    	for(int i=first[root];i;i=nxt[i]) if(to[i]!=fa) qmin(f[root],f[to[i]]+sqr(siz[root]-siz[to[i]]));
    	int tot=0;
    	for(int i=first[root];i;i=nxt[i]) if(to[i]!=fa) a[++tot]=mp(siz[to[i]],to[i]);
    	if(!tot) {
    		f[root]=1;
    		return ;
    	}
    	sort(a+1,a+tot+1);
    	int top=0; q[++top]=mp(2ll*siz[a[1].sc],f[a[1].sc]+sqr(siz[a[1].sc])-2ll*n*siz[a[1].sc]);
    	for(int i=2;i<=tot;i++) {
    		while(top&&cal(q[top-1],a[i].fr)<cal(q[top],a[i].fr)) top--;
    		qmin(res,cal(q[top],a[i].fr)+f[a[i].sc]+sqr(siz[a[i].sc])-2ll*n*siz[a[i].sc]+1ll*n*n);
    		pair<ll,ll> temp=mp(2ll*siz[a[i].sc],f[a[i].sc]+sqr(siz[a[i].sc])-2ll*n*siz[a[i].sc]);
    		q[++top]=temp;
    	}
    }
    
    signed main() {
    //	freopen("test.in","r",stdin);
    	read(n);
    	if(n==2) {
    		puts("2");
    		return 0;
    	}
    	for(int i=1;i<n;i++) {
    		read(u,v);
    		d[u]++,d[v]++;
    		add(u,v);
    	}
    	int rt;
    	for(int i=1;i<=n;i++) if(d[i]>1) {
    		rt=i;
    		break;
    	}
    	res=1ll*n*n;
    	work(rt,rt);
    	ll ans=1ll*n*(n-1);
    	ans+=1ll*n*n-res;
    	printf("%I64d
    ",ans/2);
    	return 0;
    }
    

    E Alesya and Discrete Math

    看到了题目,满脸的不可做,(于是我们看一下题解。所以我就把题解翻译一下就好了。

    考虑朴素做法,不失一般性,我们设n为偶数,那么显然我们可以用二分找到使得(f_i(x_i)=frac{L}{2})(x_i),那么按照(x_i)从大到小排序并重新编号,可以发现这个一定是对的。同时这个问题也被分成了两个规模为(frac{n}{2})的子问题,那么复杂度(T(n)=2T(frac{n}{2})+O(nlog w) , T(n)=O(nlog nlog w)),这个是过不了的,所以考虑优化这个过程。

    我们要把它分成两个子问题,所以可以随机一个选一个函数(f_i),二分出上面的(x_i),那么把(f_j(x_i)>frac{L}{2})的函数放在左边,反之放在右边,如果等于的话就先单独记出来,能填到左边就填到左边,直到左边放到(frac{n}{2})个数,然后剩下的丢到右边。这时如果左边恰有(frac{n}{2})个数,那么完成,否则如果少于,就向右边找,否则向左边找。这个复杂度是(O(nlog n+nlog w))

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<queue>
    #include<cctype>
    #define qmin(x,y) (x=min(x,y))
    #define qmax(x,y) (x=max(x,y))
    #define vic vector<int>
    #define vit vic::iterator
    #define pir pair<int,int>
    #define fr first
    #define sc second
    #define mp(x,y) make_pair(x,y)
    #define rsort(x,y) sort(x,y),reverse(x,y)
    using namespace std;
    
    inline char gc() {
    //	static char buf[100000],*p1,*p2;
    //	return (p1==p2)&&(p2=(p1=buf)+fread(buf,1,100000,stdin),p1==p2)?EOF:*p1++;
    	return getchar();
    }
    
    template<class T>
    int read(T &ans) {
    	ans=0;char ch=gc();T f=1;
    	while(!isdigit(ch)) {
    		if(ch==EOF) return -1;
    		if(ch=='-') f=-1;
    		ch=gc();
    	}
    	while(isdigit(ch))
    		ans=ans*10+ch-'0',ch=gc();
    	ans*=f;return 1;
    }
    
    template<class T1,class T2>
    int read(T1 &a,T2 &b) {
    	return read(a)!=EOF&&read(b)!=EOF?2:EOF;
    }
    
    template<class T1,class T2,class T3>
    int read(T1 &a,T2 &b,T3 &c) {
    	return read(a,b)!=EOF&&read(c)!=EOF?3:EOF;
    }
    
    typedef long long ll;
    const int Maxn=1100;
    const int inf=0x3f3f3f3f;
    
    int a[Maxn],b[Maxn],c[Maxn],tims;
    ll n,L,v;
    pair<ll,ll> ans[Maxn];
    
    ll query(ll a,ll b) {
    	printf("? %I64d %I64d
    ",a,b);
    	fflush(stdout); ll ans;
    	read(ans);
    //	ans=b;
    //	tims++;
    	return ans;
    }
    
    ll find(int x,ll k,ll l,ll r) {
    	ll mid=l+r>>1;
    	while(1) {
    		ll y=query(x,mid);
    		if(y==k) return mid;
    		if(y<k) l=mid+1;
    		else r=mid-1;
    		mid=l+r>>1;
    	}
    }
    
    void kth(int l,int r,int k,ll ql,ll qr) {
    	if(l==r) return ;
    	int x=rand()%(r-l+1)+l;
    	ll y=find(a[x],(L/n)*k,ql,qr);
    	int mid=k-l+1;
    	int l1=l-1,l2=r+1,l3=0;
    	c[++l3]=a[x];
    	for(int i=l;i<=r;i++) {
    		if(i==x) continue;
    		ll sxz=query(a[i],y);
    		if(sxz<(L/n)*k) b[--l2]=a[i];
    		if(sxz==(L/n)*k) c[++l3]=a[i];
    		if(sxz>(L/n)*k) b[++l1]=a[i];
    	}
    	while(l1<k&&l3) b[++l1]=c[l3--];
    	if(l1==k) {
    		v=y;
    		while(l3) b[--l2]=c[l3--];
    		for(int i=l;i<=r;i++) a[i]=b[i];
    		return ;
    	}
    	if(l1<k) {
    		for(int i=l;i<=r;i++) a[i]=b[i];
    		kth(l1+1,r,k,ql,qr);
    		return ;
    	}
    	while(l3) b[--l2]=c[l3--];
    	for(int i=l;i<=r;i++) a[i]=b[i];
    	kth(l,l1,k,ql,qr);
    }
    
    void solve(int l,int r,ll ql,ll qr) {
    	if(l==r) {
    		ans[a[l]]=mp(ql,qr);
    		return ;
    	}
    	int mid=l+r>>1;
    	kth(l,r,mid,ql,qr);
    	ll x=v;
    	solve(l,mid,ql,x);
    	solve(mid+1,r,x,qr);
    }
    
    signed main() {
    //	freopen("test.in","r",stdin);
    //	freopen("out","w",stdout);
    	read(n,L);
    	for(int i=1;i<=n;i++) a[i]=i;
    	solve(1,n,0,1000000000000000000ll);
    	puts("!");
    	for(int i=1;i<=n;i++) printf("%I64d %I64d
    ",ans[i].fr,ans[i].sc);
    	fflush(stdout);
    //	printf("%d
    ",tims);
    	return 0;
    }
    
  • 相关阅读:
    day 5
    Python学习(十三)—— 面向对象程序设计
    Python学习(十二)—— 常见模块
    Python学习(十一)—— 程序解耦、模块、包
    Python学习(十)—— 装饰器和函数闭包
    Python学习(八)——文件操作:读、写
    Python学习(七)——匿名函数、map函数、filter函数、reduce函数与其他内置函数
    Python学习(六)—— 函数、全局变量与局部变量
    Python学习(五)—— 集合和字符格式化
    Python学习(四)—— 列表和元组的类中方法
  • 原文地址:https://www.cnblogs.com/shanxieng/p/11077328.html
Copyright © 2011-2022 走看看