zoukankan      html  css  js  c++  java
  • Codeforces 788 (Div. 1)

    788 A

    题意

    给你一个长度为 (n) 的序列 (a) ,定义函数

    其中 (1le l<rle n)
    求对于所有可能的 (l,r,f(l,r)) 的最大值
    ((2le nle 100000))

    Examples

    Input
    5
    1 4 2 3 1
    Output
    3
    Input
    4
    1 5 4 7
    Output
    6

    (dp[i][0]) 为未计算当前节点能达到的最大值, (dp[i][1]) 为计算当前节点能达到的最大值.
    每枚举一个 (i)(ans) 都取一遍 (max)
    转移方程:

    dp[i][0]=max(dp[i-1][1]-s[i],0);
    dp[i][1]=max(dp[i-1][0]+s[i],s[i]);
    ans=max(ans,max(dp[i][0],dp[i][1]));
    

    788 B

    题意

    给你一张图,有自环,无重边,找出一条路径,使得它经过所有的边,且经过这些边的其中两条恰好 (1) 次,经过其他边恰好 (2) 次。
    求出所有满足条件的路径数量。
    ((1le n,mle 10^6))

    Examples

    Input
    5 4
    1 2
    1 3
    1 4
    1 5
    Output
    6
    Input
    5 3
    1 2
    2 3
    4 5
    Output
    0
    Input
    2 2
    1 1
    1 2
    Output
    1

    设对于一对边,如果存在一条合法路径,使这条路径经过着两条边恰好 (1) 次,那么我们称这一对边是合法的。
    经过一番波折,我们推出:两两非自环边搭配必定合法;自环与任意一条边(可以是自环,也可以不是)搭配都合法。
    最后累计。

    788 C

    题意

    (k) 瓶不同浓度的可乐,每瓶1000mL,现在要求配一瓶浓度为 (n) mL/1000mL 的可乐,问最少需要几瓶。((0 ≤ n ≤ 1000, 1 ≤ k ≤ 10^6))

    Examples

    Input
    400 4
    100 300 450 500
    Output
    2
    Input
    50 2
    100 25
    Output
    3

    将每瓶饮料的浓度减去 (n)
    题目可以转换为求一条最短路,这条最短路上的权值之和为 (0) ,且长度最小
    我们发现,合法的浓度不会超过 (2000)
    于是用dijkstra搞一下就好了
    后来发现其实只需要一个bfs!!

    788 D

    题意

    交互题
    平面上有 (n) 条直线,与坐标轴平行。现在,你有至多 (3×10^5) 次机会询问,每次询问形如 (0;x;y) ,系统将返回与这个点距离最近的直线到它的距离。
    直到已知所有直线的解析式,要求输出。
    ((1le nle 2×10^4,直线坐标,询问坐标le 10^8))

    Example

    Input
    1
    1
    3
    2
    Output
    0 1 2
    0 -2 -2
    0 5 6
    0 -2 2
    1 1 2
    2
    0 -3

    从点 ((-10^8,-10^8)) 沿直线 (y=x) 向上询问
    设询问结果为ret
    如果ret==0,那么将当前位置向右上平移1距离
    否则将当前位置向右上平移ret距离
    这样的话会 ( ext{TLE}) 一个点,需要加一个剪枝
    就是如果当前搜到一个点ret!=0,且这个点向上100距离搜到的点ret也!=0,那么直接向上跳100距离
    好了

    788 E

    题意

    (n) 个士兵,要选5个参加比赛
    选的5个人合法的条件是:设这5个人的下标为 (i,j,k,l,p) ,满足 (1le i<j<k<l<ple n)(a_ile a_j = a_k = a_l ≥ a_p)
    现在有 (m) 次操作,每次操作规定某一个士兵不能作为 (j,k,l) 参加比赛或者能作为...参加比赛
    对于每次操作,需要输出操作后选择5个人的方案数
    (10^9+7)
    ((1le n,mle 10^5,1le a_ile 10^9))

    Examples

    Input
    6
    1 1 1 1 1 1
    2
    1 3
    2 3
    Output
    1
    6
    Input
    8
    3 4 4 2 4 5 4 1
    3
    1 5
    2 5
    1 2
    Output
    1
    6
    2

    第一步:树状数组+离散化,维护 (pre[i],nxt[i]) ,分别表示 (a[i]) 前面的数中 (le a[i]) 的有多少个, (a[i]) 后面的数中 (le a[i]) 的有多少个。
    第二步:线段树,对每个离散化的 (a[i]) 的值开一个线段树(动态开点),每个节点维护 (6) 个值: (A,B,C,AB,BC,ABC) ,表示当前节点所表示区间选出 j,k,l,j和k,k和l,j、k和l 的方案数。
    具体操作:
    先预处理出未进行任何操作时的答案。
    叶子节点初始值:

    t[p].A=pre[l];
    t[p].B=1;
    t[p].C=nxt[r];
    t[p].AB=t[p].BC=t[p].ABC=0;
    

    对于每次操作,对线段树进行单点修改。
    对于每次操作后的询问,查询区间 ([1,n])

    Code

    #include<bits/stdc++.h>
    #define maxn 200003
    #define mod 1000000007
    using namespace std;
    int Plus(long long x,long long y){return (x+=y)>=mod?x%mod:x;}
    int Minus(long long x,long long y){return (x+=mod-y)>=mod?x%mod:x;}
    int mul(long long x,long long y){return (x*=y)>=mod?x%mod:x;}
    int n,a[maxn],mp[maxn],cntmp,pre[maxn],nxt[maxn];
    namespace BIT{
    	int t[maxn];
    	void clear(){
    		for(int i=1;i<=n;i++)t[i]=0;
    	}
    	void add(int pos,int k){
    		while(pos<=n){
    			t[pos]+=k;
    			pos+=pos&-pos;
    		}
    	}
    	int query(int pos){
    		int ret=0;
    		while(pos){
    			ret+=t[pos];
    			pos-=pos&-pos;
    		}
    		return ret;
    	}
    }
    namespace SEG{
    	struct node{
    		int _2,_3,_4,_23,_34,_234,son[2];
    		node():_2(0),_3(0),_4(0),_23(0),_34(0),_234(0){son[0]=son[1]=0;}
    	}t[maxn*20];
    	int cnt,root[maxn];
    	void pushup(int p){
    		int son0=t[p].son[0],son1=t[p].son[1];
    		t[p]._2=Plus(t[son0]._2,t[son1]._2);
    		t[p]._3=Plus(t[son0]._3,t[son1]._3);
    		t[p]._4=Plus(t[son0]._4,t[son1]._4);
    		t[p]._23=Plus(mul(t[son0]._2,t[son1]._3),Plus(t[son0]._23,t[son1]._23));
    		t[p]._34=Plus(mul(t[son0]._3,t[son1]._4),Plus(t[son0]._34,t[son1]._34));
    		t[p]._234=Plus(Plus(Plus(mul(t[son0]._2,t[son1]._34),mul(t[son0]._23,t[son1]._4)),t[son0]._234),t[son1]._234);
    	}
    	void change(int& p,int l,int r,int pos,bool k){
    		if(p==0)p=++cnt;
    		if(l==r){
    			t[p]._2=k*pre[pos];
    			t[p]._3=k;
    			t[p]._4=k*nxt[pos];
    			return;
    		}
    		int mid=(l+r)>>1;
    		if(pos<=mid)change(t[p].son[0],l,mid,pos,k);
    		else change(t[p].son[1],mid+1,r,pos,k);
    		pushup(p);
    	}
    	int query(int p){
    		return t[p]._234;
    	}
    }
    int main(){
    	scanf("%d",&n);
    	for(int i=1;i<=n;i++){
    		scanf("%d",a+i);
    		mp[++cntmp]=a[i];
    	}
    	sort(mp+1,mp+cntmp+1);
    	cntmp=unique(mp+1,mp+cntmp+1)-mp-1;
    	for(int i=1;i<=n;i++)a[i]=lower_bound(mp+1,mp+cntmp+1,a[i])-mp;
    	for(int i=1;i<=n;i++){
    		pre[i]=BIT::query(a[i]);
    		BIT::add(a[i],1);
    	}
    	BIT::clear();
    	for(int i=n;i>=1;i--){
    		nxt[i]=BIT::query(a[i]);
    		BIT::add(a[i],1);
    	}
    	int ans=0;
    	for(int i=1;i<=n;i++){
    		ans=Minus(ans,SEG::query(SEG::root[a[i]]));
    		SEG::change(SEG::root[a[i]],1,n,i,1);
    		ans=Plus(ans,SEG::query(SEG::root[a[i]]));
    	}
    	int Q;
    	scanf("%d",&Q);
    	while(Q--){
    		int mo,x;
    		scanf("%d%d",&mo,&x);
    		ans=Minus(ans,SEG::query(SEG::root[a[x]]));
    		if(mo==1)SEG::change(SEG::root[a[x]],1,n,x,0);
    		else SEG::change(SEG::root[a[x]],1,n,x,1);
    		ans=Plus(ans,SEG::query(SEG::root[a[x]]));
    		printf("%d
    ",ans);
    	}
    	return 0;
    }
    
    
  • 相关阅读:
    sqoop安装并配置连接数据库
    Mapreduce自定义数据类型
    MapReduce入门(三)倒排索引
    复合式MapReduce之ChainJob
    android 各种xml的作用
    Android ViewPager实现软件的第一次加载的滑动效果
    Android调用系统相机和文件浏览器
    Android样式的编写格式
    Android 按钮按下效果
    Android圆角矩形的实现
  • 原文地址:https://www.cnblogs.com/BlogOfchc1234567890/p/10415222.html
Copyright © 2011-2022 走看看