您的位置:首页 > 其它

数颜色 (二分查找 主席树)

2017-10-23 19:12 211 查看

数颜色

10.23











写了个主席树,结果Tdiao了。。。

#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cstring>
#define N 300010
using namespace std;

struct node{
int sum;
node *ls, *rs;
void update( ){
sum = ls->sum + rs->sum;
}
}pool[N * 60], *tail = pool, *root
, *null;

int n, m, maxx = 0;
int a
;

inline void init(){
null = ++tail;
null->ls = null->rs = null;
null->sum = 0;
}

inline node *newnode(){
node* nd = ++tail;
nd->sum = 0;
nd->ls = nd->rs = null;
return nd;
}

inline void insert(node *ne, node * &nd, int lf, int rg, int pos){
nd = newnode();
nd->sum = ne->sum + 1;
nd->ls = ne->ls, nd->rs = ne->rs;
if(lf == rg) return ;
int mid = (lf + rg) >> 1;
if(pos <= mid) insert(ne->ls, nd->ls, lf, mid, pos);
else insert(ne->rs, nd->rs, mid+1, rg, pos);
nd->update();
}

inline void modify(node *nd, int lf, int rg, int pos, int delta){
node* ne = newnode();
if(lf == rg){
nd->sum += delta;
return ;
}
int mid = (lf + rg) >> 1;
if(pos <= mid) ne->ls = nd->ls->ls, ne->rs = nd->ls->rs, ne->sum = nd->ls->sum, nd->ls = ne, modify(nd->ls, lf, mid, pos, delta);
else ne->ls = nd->rs->ls, ne->rs = nd->rs->rs, ne->sum = nd->rs->sum, nd->rs = ne, modify(nd->rs, mid+1, rg, pos, delta);
nd->update();
}

inline int query(node *ne, node *nd, int lf, int rg, int pos){
if(lf == rg) return nd->sum - ne->sum;
int mid = (lf + rg) >> 1;
if(pos <= mid) return query(ne->ls, nd->ls, lf, mid, pos);
else return query(ne->rs, nd->rs, mid+1, rg, pos);
}

int main(){
//freopen ("color2.in", "r", stdin);
freopen ("color.in", "r", stdin);
freopen ("color.out", "w", stdout);
//cout << sizeof(pool) << endl;
init();
scanf("%d%d", &n, &m);
for(int i=1; i<=n; i++) scanf("%d", &a[i]);
int lim = 300010;
root[0] = newnode();
for(int i=1; i<=n; i++) insert(root[i-1], root[i], 1, lim, a[i]);
while( m-- ){
int opt, L, R, C;
scanf("%d", &opt);
if(opt == 1){
scanf("%d%d%d", &L, &R, &C);
printf("%d\n", query(root[L-1], root[R], 1, lim, C));
}
else{
scanf("%d", &L);
modify(root[L], 1, lim, a[L], -1);
modify(root[L], 1, lim, a[L+1], 1);
swap(a[L], a[L+1]);
}
}
return 0;
}


粘排序,二分查找的做法吧

#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cstring>
#include <vector>
#define N 300010
using namespace std;

int n, m;
int a
;
vector <int> b
;

int main() {
freopen("color.in", "r", stdin);
freopen("color.out", "w", stdout);
scanf("%d%d", &n, &m);
for (int i=1; i<=n; i++) {
scanf("%d", &a[i]);
b[a[i]].push_back(i);
}
for (int i=1; i<=n; i++) sort(b[i].begin(), b[i].end());
for (int i=1, x, l, r, c; i<=m; i++) {
scanf("%d", &x);
if (x == 1) {
scanf("%d%d%d", &l, &r, &c);
printf("%d\n", (int)(upper_bound(b[c].begin(), b[c].end(), r) - lower_bound(b[c].begin(), b[c].end(), l)));
}
else {
scanf("%d", &x);
if (a[x] != a[x + 1]) {
(*lower_bound(b[a[x]].begin(), b[a[x]].end(), x))++;
(*lower_bound(b[a[x + 1]].begin(), b[a[x + 1]].end(), x + 1))--;
swap(a[x], a[x + 1]);
}
}
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: