zoukankan      html  css  js  c++  java
  • Codeforces round 1083

    Div1 526

    • 这个E考试的时候没调出来真的是耻辱.jpg

    A

    求个直径就完事

    #include<cstdio>
    #include<algorithm>
    #include<cmath>
    #include<cstring>
    #include<iostream>
    using namespace std;
    #define ll long long
    struct miku
    {
    	int to,next,val;
    }e[600010];
    int a[300010];
    int head[300010];
    int cnt;
    int n;
    ll ans;
    ll f[300010];
    void add(int x,int y,int z)
    {
    	e[cnt]=(miku){y,head[x],z};
    	head[x]=cnt++;
    }
    void dfs(int x,int from)
    {
    	f[x]=a[x];
    	ans=max(ans,(ll)a[x]);
    	for(int i=head[x];i!=-1;i=e[i].next)
    	{
    		int to1=e[i].to;
    		if(to1!=from)
    		{
    			dfs(to1,x);
    			ans=max(ans,f[x]+f[to1]-e[i].val);
    			f[x]=max(f[x],f[to1]+a[x]-e[i].val);
    		}
    	}
    }
    int main()
    {
    	scanf("%d",&n);
    	memset(head,-1,sizeof(head));
    	for(int i=1;i<=n;i++)
    	{
    		scanf("%d",&a[i]);
    	}
    	for(int i=1,x,y,z;i<n;i++)
    	{
    		scanf("%d%d%d",&x,&y,&z);
    		add(x,y,z);
    		add(y,x,z);
    	}
    	dfs(1,0);
    	printf("%lld
    ",ans);
    }
    

    B

    可以发现,最优答案显然是能劈叉就劈叉...

    然后这还是个特判题,有一些边界条件需要处理清楚...

    #include <cstdio>
    #include <algorithm>
    #include <cmath>
    #include <cstring>
    #include <cstdlib>
    #include <queue>
    #include <iostream>
    #include <bitset>
    using namespace std;
    #define N 500005
    #define ll long long
    char s[N],t[N];
    ll ans;
    int n,k,now,tmp;
    int main()
    {
    	scanf("%d%d%s%s",&n,&k,s+1,t+1);s[n+1]='#';
    	if(k==1)return printf("%d
    ",n),0;
    	for(now=1;s[now]==t[now];now++);
    	if(now>n)return printf("%d
    ",n),0;ans=now+1;
    	for(int i=now+1;i<=n;i++)
    	{
    		tmp=tmp<<1;
    		if(s[i]=='a')tmp++;
    		if(t[i]=='b')tmp++;
    		tmp=min(k-2,tmp);
    		ans+=tmp+2;
    	}
    	printf("%lld
    ",ans);
    }//   
    

    C

    • 打死我也不会写的
    • (极有可能真香

    一看就知道是个傻逼题。

    线段树维护值域,然后就是求出$l,r$这段的链长啥样就行...

    然后判断这俩链是否能转化为同一个链...

    D

    $O(n^2)$枚举+验证就可以了...

    然后可以想到维护处$L_i$和$R_i$表示$i$这个数左边第一个和它一样的,和右边第一个和它一样的...

    然后考虑以$i$为结尾的答案是什么,(ans=sumlimits_{j=1}[i,j] imes (j-max{ L_{j...i}}) imes(min{R_{j...i}}-i)),$[i,j]$表示,$i...j$满足要求

    那么考虑$[i,j]$可以直接在枚举$i$的时候维护出来,$L_j$和$R_j$也可以在同时用单调栈维护出来,那么上面这个式子可以拆成$4$个部分,分别在线段树上再维护一下就好了...

    代码没有

    E

    傻逼斜率优化!

    #include <cstdio>
    #include <algorithm>
    #include <cmath>
    #include <cstring>
    #include <cstdlib>
    #include <queue>
    #include <iostream>
    #include <bitset>
    using namespace std;
    #define N 1000005
    #define ll long long
    struct node{ll x,y,val;}a[N];
    int sta[N],top,n;
    ll f[N],ans;
    inline bool cmp(const node &a,const node &b){return a.x==b.x?a.y<b.y:a.x<b.x;}
    #define K(i) (a[i].x)
    #define B(i) (f[i])
    #define Y(i,j) (-K(i)*a[j].y+B(i))
    
    bool cmp1(int i,int j,int k)
    {
    	long double x=(long double)(K(i)-K(k))*(B(j)-B(i));
    	long double y=(long double)(K(i)-K(j))*(B(k)-B(i));
    	return x>=y;
    }
    
    int find(int x)
    {
    	int l=0,r=top;
    	while(l<r)
    	{
    		int m=(l+r)>>1;
    		if(Y(sta[m],x)<Y(sta[m+1],x))l=m+1;
    		else r=m;
    	}return sta[l];
    }
    
    int main()
    {
    	scanf("%d",&n);
    	for(int i=1;i<=n;i++)scanf("%lld%lld%lld",&a[i].x,&a[i].y,&a[i].val);
    	sort(a+1,a+n+1,cmp);a[0].x=0,a[0].y=1<<30;
    	for(int i=1;i<=n;i++)
    	{
    		int p=find(i);
    		f[i]=f[p]+(a[i].x-a[p].x)*a[i].y-a[i].val;ans=max(ans,f[i]);
    		while(top>=1&&cmp1(i,sta[top-1],sta[top]))top--;
    		sta[++top]=i;
    	}
    	printf("%lld
    ",ans);
    }
    

    F

    是个根号算法,就算了.jpg

  • 相关阅读:
    终于等到你---订餐系统之负载均衡(nginx+memcached+ftp上传图片+iis)
    订餐系统之同步饿了么商家订单
    订餐系统之同步口碑外卖商家菜单与点点送订单
    基于SuperSocket的IIS主动推送消息给android客户端
    基于mina框架的GPS设备与服务器之间的交互
    订餐系统之微信支付,踩了官方demo的坑
    订餐系统之自动确认淘点点订单
    订餐系统之Excel批量导入
    移除首页->重回首页
    订餐系统之获取淘宝外卖订单
  • 原文地址:https://www.cnblogs.com/Winniechen/p/10353916.html
Copyright © 2011-2022 走看看