19 上海网络赛 B. Light bulbs (线段树动态开点 卡过去)或者(差分 正解)

传送门

题意:N个灯泡,m次操作,每次选定一个区间,将这些灯泡的状态反转,求最后亮着的灯泡的数量。

思路: 差分,线段树 ,分块应该都可以,但这题卡时间,卡内存,差分是正解。

区间反转奇数次的才需要统计,偶数次的不需要 , 例如 ;(1,6)(4,8)只需统计(1,3)和(7,8)

 

差分 正解

#include 
#include 
#include 
#include 
#include 
#include 
#define mems(a,b) memset(a,b,sizeof(a))
using namespace std;
typedef long long ll;
const int N=1e5+5;

struct node
{
    int a,b;
}s[2010];
bool cmp(node x,node y)
{
    return x.a

线段树 动态开点 卡时间过去的

#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#define ull unsigned long long
#define Mod(x) (x+mod)%mod
#define lson l,mid,rt<<1
#define rson mid+1,r,rt<<1|1
#define rep(i,a,b) for(int i=a;i<=b;i++)
#define mems(a,b) memset(a,b,sizeof(a))
using namespace std;
typedef long long ll;
const int N=1e5+5;
const double pi=acos(-1);
const int inf=0x3f3f3f3f;
inline int read(){
   int s=0,w=1;
   char ch=getchar();
   while(ch<'0'||ch>'9'){if(ch=='-')w=-1;ch=getchar();}
   while(ch>='0'&&ch<='9') s=s*10+ch-'0',ch=getchar();
   return s*w;
}
int id;
struct node
{
    int sum,l,r,lazy;
}se[N];
inline int build()
{
    ++id;
    se[id].l=se[id].r=se[id].sum=0;
    se[id].lazy=0;
    return id;
}
void pushdown(int l,int r,int rt)
{
    if(se[rt].lazy==0) return;
    int mid=(l+r)>>1;
    if(l!=r)
    {
        if(se[rt].l==0) se[rt].l=build();
        if(se[rt].r==0) se[rt].r=build();
        se[se[rt].l].sum=(mid-l+1)-se[se[rt].l].sum;
        se[se[rt].r].sum=(r-mid)-se[se[rt].r].sum;
        se[se[rt].l].lazy^=1;
        se[se[rt].r].lazy^=1;
    }
    se[rt].lazy=0;
}
void update(int l,int r,int L,int R,int rt)
{
    if(L<=l&&r<=R)
    {
        se[rt].lazy^=1;
        se[rt].sum=(r-l+1)-se[rt].sum;
        return ;
    }
    pushdown(l,r,rt);
    int mid=(l+r)>>1;
    if(L<=mid)
    {
        if(se[rt].l==0)
            se[rt].l=build();
        update(l,mid,L,R,se[rt].l);
    }
    if(R>mid)
    {
        if(se[rt].r==0)
            se[rt].r=build();
        update(mid+1,r,L,R,se[rt].r);
    }
    se[rt].sum=se[se[rt].l].sum+se[se[rt].r].sum;
}

int main()
{
    int u,p=1;
    u=read();
    while(u--)
    {
        int n,m;
        n=read();m=read();
        id=0;
        build();
        for(int i=1;i<=m;i++)
        {
            int l,r;
            l=read();r=read();
            l++;r++;
            update(1,n,l,r,1);
        }
        printf("Case #%d: %d\n",p++,se[1].sum);
    }
    return 0;
}

 

你可能感兴趣的:(【线段树】,【19区域赛网络赛】)