线段树WA on #7 求助!
  • 板块CF240F TorCoder
  • 楼主ShiRoZeTsuHL卜奎BBQ!
  • 当前回复0
  • 已保存回复0
  • 发布时间2023/7/24 11:50
  • 上次更新2023/11/3 07:57:27
查看原帖
线段树WA on #7 求助!
678858
ShiRoZeTsuHL卜奎BBQ!楼主2023/7/24 11:50

交了好几次,但是一直WA #7,求助

#include <iostream>
#include <cstdio>
using namespace std;
const int maxn = 1e5 + 5;

#define ls (id << 1)
#define rs (id << 1 | 1)
#define mid ((l + r) >> 1)

int n, m;
int p[27];
char s[maxn], ans[maxn];
//s 是原字符串,ans 是答案字符串

struct SEG {
	int base; //base 是这个线段树存储的字符编号(比如 'a' 为 1)
	int t[maxn<<2], lazy[maxn<<2];
   	//t 是区间的字符总数,lazy 是修改标记
	void build(int l, int r, int id) {
		if(l == r) t[id] = (s[l] == base+'a'-1);
		else {
			build(l, mid, ls); build(mid+1, r, rs);
			t[id] = t[ls] + t[rs];
		}
	}
	void pushdown(int l, int r, int id) {
     		//没有操作时lazy为0;区间修改为 0 时 lazy 为 1;区间修改为 1 时 lazy 为 2;
		t[ls] = (mid-l+1) * (lazy[id] - 1);
		t[rs] = (r-mid) * (lazy[id] - 1);
		lazy[ls] = lazy[rs] = lazy[id];
		lazy[id] = 0;
	}
	void modify(int l, int r, int ql, int qr, int id, int k) {
		if(ql <= l && r <= qr) {
			t[id] = (r-l+1) * k;
			lazy[id] = k+1;
			return;
		}
		if(lazy[id]) pushdown(l, r, id);
		if(ql <= mid) modify(l, mid, ql, qr, ls, k);
		if(mid < qr) modify(mid+1, r, ql, qr, rs, k);
		t[id] = t[ls] + t[rs];
	}
	int query(int l, int r, int ql, int qr, int id) {
		if(ql <= l && r <= qr) return t[id];
		if(lazy[id]) pushdown(l, r, id);
		int res = 0;
		if(ql <= mid) res += query(l, mid, ql, qr, ls);
		if(mid < qr) res += query(mid+1, r, ql, qr, rs);
		return res;
	}
} seg[27];

int main() {
	freopen("input.txt", "r", stdin);
	freopen("output.txt", "w", stdout);
	
	scanf("%d %d", &n, &m);
	scanf("%s", s+1);
	for(int i = 1; i <= 26; i++) seg[i].base = i, seg[i].build(1, n, 1);
	for(int i = 1; i <= m; i++) {
		int l, r; scanf("%d %d", &l, &r);
		int c = 0;
        	//c用来统计区间有多少个字符出现奇数次
		for(int j = 1; j <= 26; j++) {
			p[j] = seg[j].query(1, n, l, r, 1);
            		//p[j] 用来存储 j 号字符区间内出现的次数
			c += (p[j] & 1);
		}
		
		if(c > 1) continue;
		for(int j = 1; j <= 26; j++) {
			seg[j].modify(1, n, l, r, 1, 0);
            		//清空
			if(p[j]&1) seg[j].modify(1, n, mid, mid, 1, 1), p[j]--;
            		//处理奇数次的字符
			if(!p[j]) continue;
			seg[j].modify(1, n, l, l+(p[j]>>1)-1, 1, 1);
			seg[j].modify(1, n, r-(p[j]>>1)+1, r, 1, 1);
		}
	}
	
	for(int i = 1; i <= 26; i++)
	for(int j = 1; j <= n; j++)
		if(seg[i].query(1, n, j, j, 1)) ans[j] = i+'a'-1;
	printf("%s\n", ans+1);
	return 0;
}
2023/7/24 11:50
加载中...