Jeanny
寂兮,寥兮,独立不改,周行而不殆

loj 分块1

#include<bits/stdc++.h>
using namespace std;
int n,a[50005],sum[50005],L[50005],R[50005],belong[50005];
void build(){
	int block = sqrt(n);
	int num = n/block;
	if(num % block) num++;
	for(int i = 1; i <= num; i++){
		L[i] = (i-1)*block + 1;
		R[i] = i*block;
	}
	R[num] = n;
	for(int i = 1; i <= n; i++)
		belong[i] = (i-1)/block + 1; 
}
void add(int l, int r, int val){
	int s = belong[l], t = belong[r];
	if(s == t){
		for(int i = l; i <= r; i++)//err:s,t
			a[i] += val;
		return;
	}
	if(l != L[s]){
		for(int i = l; i <= R[s]; i++)
			a[i] += val;
		s++;
	}
	if(r != R[t]){
		for(int i = L[t]; i <= r; i++)
			a[i] += val;
		t--;
	} 
	for(int i = s; i <= t; i++)
		sum[i] += val;
}
int main(){ 
	scanf("%d",&n);
	for(int i = 1; i <= n; i++)
		scanf("%d",&a[i]);
	build(); int opt,l,r,c;
	for(int i = 1; i <= n; i++){
		scanf("%d%d%d%d",&opt,&l,&r,&c);
		if(opt == 0) add(l, r, c); 
		else if(opt == 1){
			printf("%d\n",a[r] + sum[belong[r]]);//belong[r] err:a[r] + sum[r] 
		}
	}
	return 0;
} 

P2801 教主的魔法

洛谷题解

#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<algorithm>
#define long long int
using namespace std;
int a[1000005],d[1000005],block,n,q,x,y,z,lf[1000005],rg[1000005],num,belong[1000005],tag[1000005];
char op[3];
void build(){
  block = sqrt(n);
  num = n / block;
  if(n % block) num++;
  for(int i = 1; i <= num; i++){
    lf[i] = (i - 1) * block + 1, rg[i] = i * block;
  }//循环里写的sort
  rg[num] = n;
  for(int i = 1; i <= n; i++)
    belong[i] = (i - 1)/block + 1;
  for(int i = 1; i <= num; i++)
  	sort(d + lf[i], d + rg[i] + 1);//每一段都进行排序
}
void add(int l, int r, int val){
  int st = belong[l], ed = belong[r];
  if(st == ed){
    for(int i = l; i <= r; i++)
      a[i] += val;
    for(int i = lf[st]; i <= rg[st]; i++) d[i] = a[i];
    sort(d + lf[st], d + rg[st] + 1);
    return;
  }
  if(l != lf[st]){
    for(int i = l; i <= rg[st]; i++) a[i] += val;
    for(int i = lf[st]; i <= rg[st]; i++) d[i] = a[i];
    sort(d + lf[st], d + rg[st] + 1);
    st++;
  }
  if(r != rg[ed]){
    for(int i = lf[ed]; i <= r; i++) a[i] += val;
    for(int i = lf[ed]; i <= rg[ed]; i++) d[i] = a[i];
    sort(d + lf[ed], d + rg[ed] + 1);
    ed--;
  }
  for(int i = st; i <= ed; i++) tag[i] += val;//+=
}
int query(int l, int r, int c){
  int ans = 0, st = belong[l], ed = belong[r];
  if(st == ed){
    for(int i = l; i <= r; i++)
      if(a[i] + tag[st] >= c) ans++;
    return ans;
  }
  if(l != lf[st]){
    for(int i = l ; i <= rg[st]; i++)
      if(a[i] + tag[st] >= c) ans++;//error:without tag
    st++;
  }
  if(r != rg[ed]){
    for(int i = lf[ed] ; i <= r; i++)
      if(a[i] + tag[ed] >= c) ans++;//error:without tag
    ed--;
  }
  for(int i = st; i <= ed; i++){
  	if(c >  d[rg[i]] + tag[i] ) continue;//如果这一块最大的值都小于c,则continue
  	int id = lower_bound(d + lf[i], d + rg[i], c - tag[i]) - d;
    ans += rg[i] - id + 1;
  }
  return ans;
}
signed main(){
  scanf("%d%d",&n,&q);
  for(int i = 1; i <= n; i++){
    scanf("%d",&a[i]);//原数组
    d[i] = a[i];//排序数组
  }
  build();
  for(int i = 1; i <= q; i++){
	  scanf("%s%d%d%d",op,&x,&y,&z);
	  if(op[0] == 'M'){
	    add(x,y,z);
	  }else if(op[0] == 'A'){
	    printf("%d\n", query(x,y,z));
	  }
  }
  return 0;
}

loj 分块8

#include <bits/stdc++.h>
typedef long long ll;
const int INF = 0x7fffffff;

using namespace my_std;
using namespace ka_chang;
const int N = 100010;
int n, len, val[N], bl[N], tag[N];
inline void pushdown(int x) {
    if (tag[x] == INF) return;
    rep(i, L[x], R[x])) val[i] = tag[x];
    tag[x] = INF;
}
inline int solve(int x, int y, int c) {
    int l = bl[x], r = bl[y], res = 0;
    if (l == r) {
        pushdown(l);//标记下放 
        rep(i, x, y) {//下放之后(原来的值)进行统计 
            if (val[i] == c)
                res++;
            val[i] = c;
        }
        return res;
    }
    rep(i, l + 1, r - 1) {
        if (tag[i] == INF) {
            rep(j, (i - 1)*len + 1, i * len) {
                if (val[j] == c)
                    res++;

                val[j] = c;
            }
        } 
		else if (tag[i] == c)
            res += len;

        tag[i] = c;
    }
    retag(l), retag(r);//下放两边的标记 
    rep(i, x, l * len) {//左边  for(int i = x; i <= l*len; i++)
        if (val[i] == c)
            res++;

        val[i] = c;
    }
    rep(i, (r - 1)*len + 1, y) {//右边  for(int i = (r-1)*len + 1; i <= y; i++)
        if (val[i] == c)
            res++;

        val[i] = c;
    }
    return res;
}
signed main() {
    n = read(), len = sqrt(n);
    rep(i, 1, n) val[i] = read();
    rep(i, 1, n) bl[i] = (i - 1) / len + 1;
    rep(i, 1, n) tag[i] = INF;
    for(int i = 1; i <= len; i++)
		L[i] = (i - 1) * len + 1, R[i] = i * len; //每一个块的左右端点 
    rep(i, 1, n) {
        int l = read(), r = read(), c = read();
        writeln(solve(l, r, c));
    }
}
posted on 2022-04-23 17:30  Jeanny  阅读(34)  评论(0)    收藏  举报