码迷,mamicode.com
首页 > 其他好文 > 详细

模板综合

时间:2016-05-01 21:47:44      阅读:240      评论:0      收藏:0      [点我收藏+]

标签:

ctsc前例行砍手

可并堆、并查集 zoj2334

#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <algorithm>
#include <string.h>
#include <vector>
#include <math.h>
#include <limits>
#include <set>
#include <map>
using namespace std;
#define SZ 666666
int ch[SZ][2],dis[SZ],v[SZ];
int merge(int a,int b)
{
    if(!a||!b) return a+b;
    if(v[a]<v[b]) swap(a,b);
    ch[a][1]=merge(ch[a][1],b);
    if(dis[ch[a][0]]<dis[ch[a][1]]) swap(ch[a][0],ch[a][1]);
    if(!ch[a][1]) dis[a]=0;
    else dis[a]=dis[ch[a][1]]+1;
    return a;
}
int pop(int a)
{
    int t=merge(ch[a][0],ch[a][1]);
    ch[a][0]=ch[a][1]=dis[a]=0;
    return t;
}
int ff[SZ],rot[SZ];
int gf(int x) {return ff[x]?ff[x]=gf(ff[x]):x;}
int n,m;
void sol()
{
    for(int i=1;i<=n;i++) scanf("%d",v+i), ch[i][0]=ch[i][1]=dis[i]=ff[i]=0, rot[i]=i;
    scanf("%d",&m);
    while(m--)
    {
        int a,b;
        scanf("%d%d",&a,&b);
        int ga=gf(a),gb=gf(b);
        if(ga==gb) {puts("-1"); continue;}
        v[rot[ga]]/=2; v[rot[gb]]/=2;
        int aa=merge(pop(rot[ga]),rot[ga]);
        int bb=merge(pop(rot[gb]),rot[gb]);
        rot[ga]=merge(aa,bb);
        ff[gb]=ga;
        printf("%d\n",v[rot[ga]]);
    }
}
int main()
{
    while(scanf("%d",&n)!=-1) sol();
}

cdq分治 bzoj1176

#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <algorithm>
#include <string.h>
#include <vector>
#include <math.h>
#include <limits>
#include <set>
#include <map>
using namespace std;
int s,w,q=0,Q=0,ans[233333];
//tp=0 edit
//tp=1 query
//op: -1/1 for query
//    value for edit
struct cq {int x,y,op,tp,qid;}qs[233333];
bool operator < (cq a,cq b) {return a.x<b.x;}
int bits[2333333];
int sum(int x)
{
    int ans=0;
    for(;x>=1;x-=x&-x) ans+=bits[x];
    return ans;
}
void edit(int x,int y)
{
    for(;x<=w;x+=x&-x) bits[x]+=y;
}
void cdq(int l,int r)
{
    if(l>=r) return;
    int mid=(l+r)>>1;
    cdq(l,mid); cdq(mid+1,r);
    sort(qs+l,qs+mid+1);
    sort(qs+mid+1,qs+r+1);
    int cur=l;
    for(int i=mid+1;i<=r;i++)
    {
        if(qs[i].tp!=1) continue;
        int x=qs[i].x;
        while(cur<=mid&&qs[cur].x<=x)
        {
            if(qs[cur].tp==0) edit(qs[cur].y,qs[cur].op);
            ++cur;
        }
        ans[qs[i].qid]+=qs[i].op*sum(qs[i].y);
    }
    for(int i=l;i<cur;i++) if(qs[i].tp==0) edit(qs[i].y,-qs[i].op);
}
int main()
{
    scanf("%d%d",&s,&w);
    int o,a,b,c,d;
    while(1)
    {
        scanf("%d",&o);
        if(o==1)
        {
            scanf("%d%d%d",&a,&b,&c);
            ++q; qs[q].x=a; qs[q].y=b; qs[q].tp=0; qs[q].op=c;
        }
        else if(o==2)
        {
            scanf("%d%d%d%d",&a,&b,&c,&d);
            ++Q;
            ++q; qs[q].x=a-1; qs[q].y=b-1; qs[q].tp=1; qs[q].op=1; qs[q].qid=Q;
            ++q; qs[q].x=c; qs[q].y=b-1; qs[q].tp=1; qs[q].op=-1; qs[q].qid=Q;
            ++q; qs[q].x=a-1; qs[q].y=d; qs[q].tp=1; qs[q].op=-1; qs[q].qid=Q;
            ++q; qs[q].x=c; qs[q].y=d; qs[q].tp=1; qs[q].op=1; qs[q].qid=Q;
        }
        else break;
    }
    cdq(1,q);
    for(int i=1;i<=Q;i++) printf("%d\n",ans[i]);
}

二维线段树 bzoj1176

模板综合

标签:

原文地址:http://www.cnblogs.com/zzqsblog/p/5451134.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!