莫队
#include <cstdio> #include <cmath> #include <algorithm> #include <map> #include <set> #include <cstring> using namespace std; typedef long long ll; int intval; // 排序函数什么的 还有排序函数需要用到的变量都放到全局中 否则会出错. ///// 因为排序函数要求 static 表示静态 所以排序函数用到的变量也需要一个全局变量 ///// 如果不是全局变量,那么编译器将找不到这个变量.(即使在类内这个变量用了 static 但是它属于一个类) ///// 估计函数的加上static 就变成全局了的. 而类内变量还是static 类域的变量...函数是全局的! class MD { public : const static int cmaxn = 2e5+500; int date[cmaxn]; int cn, cm; int cans; struct Section { int l; int r; int id; // 询问次序标识 int ans; // 询问答案 如果用ans数组则可以省略. }op[cmaxn]; // 询问 // n个元素 m个询问 void init(int n, int m) { intval = sqrt(1.0 * n); cn = n; cm = m; // Todo : 初始化 } void setdate() { // Todo: 添加数据 } void setquery() { // Todo: 添加询问 } int left, right; // 当前区间 void add(int val) { // Todo : 区间添加一个元素的代码. } void sub(int val) { // Todo : 区间移除一个元素的代码. } static bool cmp1 (const Section &a,const Section &b) { if (a.l/intval == b.l/intval) return a.r < b.r; return a.l/intval < b.l/intval; } // m为询问的个数 void towork() { int i; // 对区间进行排序. sort(op+1, op+cm+1, cmp1); // Todo : 初始化 left = 1; right = 0; cans = 0; memset(buck, 0, sizeof(buck)); // working 注意 一般都是先扩展 后收缩 具体看题. for (i=1; i<=cm; ++i) { while (right < op[i].r) add(date[++right]); while (left > op[i].l) add(date[--left]); while (right > op[i].r) sub(date[right--]); while (left < op[i].l) sub(date[left++]); // Todo: 添加维护区间答案的代码. eg ans[op[x].id] = cans; 或者 op[i].ans = ans; // op[i].ans = cans; } } // 询问重新排序回来. 当然 也可以弄一个 ans[]数组来存答案 可以少sort一遍 // 例如,ans[op[x].id] = cans; static bool cmp2(const Section &a, const Section &b) { return a.id < b.id; } void putout() { // Todo: 输出答案 注: // sort(op+1, op+1+m, cmp2); } /* 执行顺序 md.init(n, m); md.setdate(); md.setquery(); md.towork(); md.putout(); */ };