codeforces 558EA Simple Task

开始试想直接用容器来暴力做,,,,,,

恩。。。。。线段树。。。。

记不得以前写没写过了,,,,

先来个模板先(就是那种n个询问成段更新的题)

#include<stdio.h>

#include<string.h>

#include <algorithm>

#include <bits/stdc++.h>

using namespace std;

#define lson l , m , rt << 1

#define rson m + 1 , r , rt << 1 | 1

#define root 1 , N , 1

#define LL long long

const int maxn = 111111;

LL add[maxn<<2];

LL sum[maxn<<2];

void PushUp(int rt) {

sum[rt] = sum[rt<<1] + sum[rt<<1|1];

}

void PushDown(int rt,int m) {

if (add[rt])

{

add[rt<<1] += add[rt];

add[rt<<1|1] += add[rt];

sum[rt<<1] += add[rt] * (m - (m >> 1));

sum[rt<<1|1] += add[rt] * (m >> 1);

add[rt] = 0;

}

}

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

{

add[rt] = 0;

if (l == r) {

scanf("%lld",&sum[rt]);

return ;

}

int m = (l + r) >> 1;

build(lson);

build(rson);

PushUp(rt);

}

void update(int L,int R,int c,int l,int r,int rt) {

if (L <= l && r <= R) {

add[rt] += c;

sum[rt] += (LL)c * (r - l + 1);

return ;

}

PushDown(rt , r - l + 1);

int m = (l + r) >> 1;

if (L <= m) update(L , R , c , lson);

if (m < R) update(L , R , c , rson);

PushUp(rt);

}

LL query(int L,int R,int l,int r,int rt) {

if (L <= l && r <= R) {

return sum[rt];

}

PushDown(rt , r - l + 1);

int m = (l + r) >> 1;

LL ret = 0;

if (L <= m) ret += query(L , R , lson);

if (m < R) ret += query(L , R , rson);

return ret;

}

int main() {

int N , Q;

scanf("%d%d",&N,&Q);

build(root);

while (Q --) {

char op[2];

int a , b , c;

scanf("%s",op);

if (op[0] == ‘Q‘) {

scanf("%d%d",&a,&b);

printf("%lld\n",query(a , b ,root));

} else {

scanf("%d%d%d",&a,&b,&c);

update(a , b , c , root);

}

}

return 0;

}

/*我们开26棵线段树,第i棵线段树维护的是:26个字母中排第i个的字母在各个区间的数目。*/

#include<iostream>

#include<cstring>

#include<string>

using namespace std;

int aint[400005][27], lazy[400005], i, x, y, op, n, q, aux[27], paux;

string s;

void init(int nod, int l, int r) {

if (l==r) aint[nod][int(s[l-1]-‘a‘)]=1;

else {

int mid=(l+r)/2;

init(2*nod,l,mid);

init(2*nod+1,mid+1,r);

for (int i=0; i<26; ++i) aint[nod][i]=aint[2*nod][i]+aint[2*nod+1][i];

}

}

void buildsol(int nod, int l, int r) {

if (lazy[nod]==1) {//update crescator pe fii

int p=0, nr=aint[nod][0];

int mid=(l+r)/2;

int leftlen=mid-l+1;

memset(aint[2*nod],0,sizeof(aint[2*nod]));

memset(aint[2*nod+1],0,sizeof(aint[2*nod+1]));

while (nr<=leftlen) {

aint[2*nod][p]=aint[nod][p];

++p;

nr+=aint[nod][p];

}

nr-=aint[nod][p];

if (nr<leftlen) aint[2*nod][p]=leftlen-nr;

if (leftlen>1) lazy[2*nod]=1;

aint[2*nod+1][p]=aint[nod][p]-(leftlen-nr);

++p;

while (p<26) {

aint[2*nod+1][p]=aint[nod][p];

++p;

}

if (r-mid>1) lazy[2*nod+1]=1;

lazy[nod]=0;

}

else if (lazy[nod]==2) {//update descrescator pe fii

int p=25, nr=aint[nod][25];

int mid=(l+r)/2;

int leftlen=mid-l+1;

memset(aint[2*nod],0,sizeof(aint[2*nod]));

memset(aint[2*nod+1],0,sizeof(aint[2*nod+1]));

while (nr<=leftlen) {

aint[2*nod][p]=aint[nod][p];

--p;

nr+=aint[nod][p];

}

nr-=aint[nod][p];

if (nr<leftlen) aint[2*nod][p]=leftlen-nr;

if (leftlen>1) lazy[2*nod]=2;

aint[2*nod+1][p]=aint[nod][p]-(leftlen-nr);

--p;

while (p>=0) {

aint[2*nod+1][p]=aint[nod][p];

--p;

}

if (r-mid>1) lazy[2*nod+1]=2;

lazy[nod]=0;

}

if (l==r) {

int k=0;

while (aint[nod][k]==0) ++k;

s+=char(k+‘a‘);

}

else {

int mid=(l+r)/2;

buildsol(2*nod,l,mid);

buildsol(2*nod+1,mid+1,r);

}

}

void getnumbers(int nod, int l, int r, int x, int y) {

if (lazy[nod]==1) {//update crescator pe fii

int p=0, nr=aint[nod][0];

int mid=(l+r)/2;

int leftlen=mid-l+1;

memset(aint[2*nod],0,sizeof(aint[2*nod]));

memset(aint[2*nod+1],0,sizeof(aint[2*nod+1]));

while (nr<=leftlen) {

aint[2*nod][p]=aint[nod][p];

++p;

nr+=aint[nod][p];

}

nr-=aint[nod][p];

if (nr<leftlen) aint[2*nod][p]=leftlen-nr;

if (leftlen>1) lazy[2*nod]=1;

aint[2*nod+1][p]=aint[nod][p]-(leftlen-nr);

++p;

while (p<26) {

aint[2*nod+1][p]=aint[nod][p];

++p;

}

if (r-mid>1) lazy[2*nod+1]=1;

lazy[nod]=0;

}

else if (lazy[nod]==2) {//update descrescator pe fii

int p=25, nr=aint[nod][25];

int mid=(l+r)/2;

int leftlen=mid-l+1;

memset(aint[2*nod],0,sizeof(aint[2*nod]));

memset(aint[2*nod+1],0,sizeof(aint[2*nod+1]));

while (nr<=leftlen) {

aint[2*nod][p]=aint[nod][p];

--p;

nr+=aint[nod][p];

}

nr-=aint[nod][p];

if (nr<leftlen) aint[2*nod][p]=leftlen-nr;

if (leftlen>1) lazy[2*nod]=2;

aint[2*nod+1][p]=aint[nod][p]-(leftlen-nr);

--p;

while (p>=0) {

aint[2*nod+1][p]=aint[nod][p];

--p;

}

if (r-mid>1) lazy[2*nod+1]=2;

lazy[nod]=0;

}

if (l>=x&&r<=y) {

for (int i=0; i<=25; ++i) aux[i]+=aint[nod][i];

}

else {

int mid=(l+r)/2;

if (x<=mid) getnumbers(2*nod,l,mid,x,y);

if (y>mid) getnumbers(2*nod+1,mid+1,r,x,y);

}

}

void updatecresc(int nod, int l, int r,int x, int y) {

if (l>=x&&r<=y) {

for (int i=0; i<26; ++i) aint[nod][i]=0;

int nr=aux[paux];

int len=(r-l+1);

while (nr<=len&&paux<=25) {

aint[nod][paux]=aux[paux];

++paux;

nr+=aux[paux];

}

if (paux<=25) {

nr-=aux[paux];

if (nr<len) aint[nod][paux]=len-nr;

aux[paux]-=(len-nr);

if (aux[paux]==0) ++paux;

}

if (l<r) lazy[nod]=1;

}

else {

int mid=(l+r)/2;

if (x<=mid) updatecresc(2*nod,l,mid,x,y);

if (y>mid) updatecresc(2*nod+1,mid+1,r,x,y);

for (int i=0; i<26; ++i) aint[nod][i]=aint[2*nod+1][i]+aint[2*nod][i];

}

}

void updatedesc(int nod, int l, int r, int x, int y) {

if (l>=x&&r<=y) {

for (int i=0; i<26; ++i) aint[nod][i]=0;

int nr=aux[paux];

int len=(r-l+1);

while (nr<=len&&paux>=0) {

aint[nod][paux]=aux[paux];

--paux;

if (paux>=0) nr+=aux[paux];

}

if (paux>=0) {

nr-=aux[paux];

if (nr<len) aint[nod][paux]=len-nr;

aux[paux]-=(len-nr);

if (aux[paux]==0) --paux;

}

if (l<r) lazy[nod]=2;

}

else {

int mid=(l+r)/2;

if (x<=mid) updatedesc(2*nod,l,mid,x,y);

if (y>mid) updatedesc(2*nod+1,mid+1,r,x,y);

for (int i=0; i<26; ++i) aint[nod][i]=aint[2*nod+1][i]+aint[2*nod][i];

}

}

void sortcresc(int x, int y) {

memset(aux,0,sizeof(aux));

getnumbers(1,1,n,x,y);

paux=0;

updatecresc(1,1,n,x,y);

}

void sortdesc(int x, int y) {

memset(aux,0,sizeof(aux));

getnumbers(1,1,n,x,y);

paux=25;

updatedesc(1,1,n,x,y);

}

int main(void) {

cin>>n>>q;

getline(cin,s);

getline(cin,s);

init(1,1,n);

for (; q; --q) {

cin>>x>>y>>op;

if (op==1) sortcresc(x,y);

else sortdesc(x,y);

}

s="";

buildsol(1,1,n);

cout<<s;

return 0;

}



版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-12-29 05:23:29

codeforces 558EA Simple Task的相关文章

计数排序 + 线段树优化 --- Codeforces 558E : A Simple Task

E. A Simple Task Problem's Link: http://codeforces.com/problemset/problem/558/E Mean: 给定一个字符串,有q次操作,每次操作将(l,r)内的字符升序或降序排列,输出q次操作后的字符串. analyse: 基本思想是计数排序. 所谓计数排序,是对一个元素分布较集中的数字集群进行排序的算法,时间复杂度为O(n),但使用条件很苛刻.首先对n个数扫一遍,映射出每个数字出现的次数,然后再O(n)扫一遍处理出:对于数字ai,

Codeforces 558E A Simple Task (计数排序&amp;&amp;线段树优化)

题目链接:http://codeforces.com/contest/558/problem/E E. A Simple Task time limit per test5 seconds memory limit per test512 megabytes inputstandard input outputstandard output This task is very simple. Given a string S of length n and q queries each quer

HUST 1341 A - A Simple Task(哈理工 亚洲区选拔赛练习赛)

A - A Simple Task Time Limit:1000MS    Memory Limit:131072KB    64bit IO Format:%lld & %llu SubmitStatusPracticeHUST 1341 Description As is known to all, lots of birds are living in HUST. A bird has s units of food on the first day, and eats k units

A Simple Task

A Simple Task 就像这道题的题目一样,真的是一个简单的题目,题意就是一句话:给一个数N求符合公式N = O * 2P的 O 和 P. 下面我们就一起看一下题吧. Description Given a positive integer n and the odd integer o and the nonnegative integer p such that n = o2^p. Example For n = 24, o = 3 and p = 3. Task Write a pr

HDU1339_A Simple Task【水题】

A Simple Task Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 3987    Accepted Submission(s): 2181 Problem Description Given a positive integer n and the odd integer o and the nonnegative integ

CodeForces - 344B Simple Molecules (模拟题)

CodeForces - 344B Simple Molecules Time Limit: 1000MS   Memory Limit: 262144KB   64bit IO Format: %I64d & %I64u Submit Status Description Mad scientist Mike is busy carrying out experiments in chemistry. Today he will attempt to join three atoms into

杭电 HDU ACM 1339 A Simple Task

A Simple Task Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 4180    Accepted Submission(s): 2304 Problem Description Given a positive integer n and the odd integer o and the nonnegative integ

[2016-04-26][codeforces][665C - Simple Strings]

时间:2016-04-26 10:11:21 星期二 题目编号:[2016-04-26][codeforces][665C - Simple Strings] 题目大意:给定一个字符串,问最少需要更改多少字符,使得相邻的字母都不一样,输出更改后的字符串 分析: 贪心,从左往右扫一遍数组,更改相同的元素即可 遇到的问题: 注意,相同元素必须更改后面那个元素才是最优的答案. 比如 aaa 这种情况只能更改中间那个 #include<iostream> #include<string>

[2016-04-27][codeforces][665D - Simple Subset]

时间:2016-04-27 15:16:14 星期三 题目编号:[2016-04-27][codeforces][665D - Simple Subset] 题目大意:给定n个数字的集合A,问子集最大能有多大,使得子集中两两之和是素数,输出大小和任一这样子集 分析: 至多一个1: 首先 从A取任意3个数 如果这3个数字中至多1个 1 由容斥原理可知,一定有两个数之和是偶数,并且这个偶数之和大于2(一定不是素数),所以答案子集中,大于1的数字至多只能有两个, 推广到整个A,就是如果A中至多含有1个