(線段樹統計區間種類)

2021-09-22 20:08:38 字數 3230 閱讀 6509

第14屆中北大學程式設計競賽來了,集訓隊新買了一大堆氣球,氣球一共有k種顏色(1<=k<=256),氣球的顏色從1-k編號。

zbt童心未泯,他發明了一種擺放氣球的遊戲,規則如下。

一排有n個桌子,每張桌子上只有乙個氣球插孔,即每張桌子最多只能放乙個氣球。編號分別為1-n(1<=n<=100000),每張桌子一開始是空的。現在對這張桌子要進行m次操作(1<=m<=100000),操作的種類一共有2種。

操作1:

操作指令格式: change l r c

操作含義:在編號為l至編號為r的桌子分別放置顏色為c的氣球(如果這些桌子上曾經有氣球,則取下原來的氣球。因為每張桌子上只能放置乙個氣球)

操作2:

操作指令格式: query l r

操作含義:輸出編號為l到編號為r的桌子上的氣球顏色種類數

現在他要求你寫程式來完成他的操作,程式的輸入輸出見輸入、輸出描述

輸入描述

第1行是三個整數n和m以及k,用空格隔開,分別代表桌子的個數、要進行操作指令的個數、以及氣球的顏色總數。

接下來m行,每行乙個操作指令,格式如上,保證指令中的1<=l<=r<=n, 1<=c<=k

輸出描述

如果操作指令中有查詢操作(操作2),那麼對於每個操作2輸出一行,該行中只有乙個整數即為該查詢操作的答案。

如果全部操作指令中都沒有查詢操作(操作2),那麼請輸出」 this is a boring game!」(不含引號)

樣例輸入

10 20 5

query 6 8

change 5 8 5

change 2 3 5

change 9 10 1

query 9 9

query 8 10

change 2 4 4

change 9 9 2

query 2 2

change 8 10 1

change 6 9 3

change 10 10 2

query 3 5

query 6 8

query 2 5

query 5 5

query 3 9

query 4 10

change 5 8 1

query 7 8

樣例輸出

012

1212

1341

題解:k 小的話,每個用二進位制(1<#include#include#include#include#include#include#include#include#include#include#include#include#include#define eps (1e-8)

#define max 0x3f3f3f3f

#define u_max 1844674407370955161

#define l_max 9223372036854775807

#define i_max 2147483647

#define re register

#define pushup() tree[rt]=(tree[rt<<1],tree[rt<<1|1]);

#define nth(k,n) nth_element(a,a+k,a+n); // 將 第k大的放在k位

#define ko() for(int i=2;i<=n;i++) s=(s+k)%i // 約瑟夫

#define ok() v.erase(unique(v.begin(),v.end()),v.end()) // 排序,離散化

#define catalan c(2n,n)-c(2n,n-1) (1,2,5,14,42,132,429...) // 卡特蘭數

using namespace std;

inline int read()

while(c >= '0' & c <= '9') x = x * 10 + c - '0', c = getchar();

return x * f;

}typedef long long ll;

const double pi = atan(1.)*4.;

const int inf = 0x3f3f3f3f;

const ll inf = 0x3f3f3f3f3f3f3f3fll;

const int m=63;

const int n=1e5+5;

struct funtree[n<<2],v[n<<2];

void sett(int l,int r,int rt)

int mid=l+r>>1;

sett(l,mid,rt<<1);

sett(mid+1,r,rt<<1|1);

tree[rt].bit=(tree[rt<<1].bit|tree[rt<<1|1].bit);

}void fun(int l,int r,int rt)

}void upset(int x,int y,int vel,int l,int r,int rt)

fun(l,r,rt);

int mid=l+r>>1;

if(x<=mid) upset(x,y,vel,l,mid,rt<<1);

if(y>mid) upset(x,y,vel,mid+1,r,rt<<1|1);

tree[rt].bit=(tree[rt<<1].bit|tree[rt<<1|1].bit);

}bitset<270>bb(0);

void findd(int x,int y,int l,int r,int rt)

fun(l,r,rt);

int mid=l+r>>1;

if(x<=mid)

findd(x,y,l,mid,rt<<1);

if(y>mid)

findd(x,y,mid+1,r,rt<<1|1);

}int main()

else

}if(!leap) printf("this is a boring game!\n");

return 0;

}

SPOJ DQUERY 區間種類查詢

離線做法 列舉右端點r,右端點固定時,記錄最右邊第一次出現的數字為1,比如1 2 1 2 3,0 0 1 1 1 給定l,那麼l r區間數字種類的結果是 sum r sum l 1 把詢問按r從小到大排序,我們r 1時,維護的陣列只改變r 1為1,和r 1的數之前出現的位置變為0即可。kx incl...

線段樹(區間樹)

目錄 為什麼要使用線段樹 什麼是線段樹 線段樹融合介面 線段樹實現 線段樹例題 融合介面 author administrator param public inte ce merger package com.suanfa.segmenttree 線段樹 區間樹 author administra...

線段樹 區間樹

每乙個節點儲存的是乙個區間中相應統計值 在treeindex的位置建立表示區間 l.r 的線段樹 private void buildsegmenttree int treeindex,int l,int r int lefttreeindex leftchild treeindex int rig...