CSU 1515 - Sequence (莫队)
2015-09-30 17:05
453 查看
题意
区间l, r内有几对满足|a[l]-a[r]| = 1。思路
可以发现l+=1, r和
l, r+-1都可以在O(1)内求出来,就可以用莫队了。
刚开始用map搞了好几发,连输入挂都用上了还是TLE。不就多了个log吗(斜眼
后来只能一开始离散化一下。
代码
#include <stack> #include <cstdio> #include <list> #include <cassert> #include <set> #include <fstream> #include <iostream> #include <string> #include <sstream> #include <vector> #include <queue> #include <functional> #include <cstring> #include <algorithm> #include <cctype> #pragma comment(linker, "/STACK:102400000,102400000") #include <string> #include <map> #include <cmath> //#include <ext/pb_ds/assoc_container.hpp> //#include <ext/pb_ds/hash_policy.hpp> using namespace std; //using namespace __gnu_pbds; #define LL long long #define ULL unsigned long long #define SZ(x) (int)x.size() #define Lowbit(x) ((x) & (-x)) #define MP(a, b) make_pair(a, b) #define MS(p, num) memset(p, num, sizeof(p)) #define PB push_back #define X first #define Y second #define ROP freopen("input.txt", "r", stdin); #define MID(a, b) (a + ((b - a) >> 1)) #define LC rt << 1, l, mid #define RC rt << 1|1, mid+1, r #define LRT rt << 1 #define RRT rt << 1|1 #define FOR(i, a, b) for (int i=(a); (i) < (b); (i)++) #define FOOR(i, a, b) for (int i = (a); (i)<=(b); (i)++) const double PI = acos(-1.0); const int INF = 0x3f3f3f3f; const double eps = 1e-8; const int MAXN = 1e4+10; const int MOD = 1e9+7; const int dir[][2] = { {0, 1}, {1, 0} }; const int seed = 131; int cases = 0; typedef pair<int, int> pii; const int MAXM = 1e5 + 10; int pos[MAXN]; void in(int &x){ char ch; int minus = 0; while (ch=getchar(), (ch<'0'||ch>'9') && ch!='-'); if (ch == '-') minus = 1, x = 0; else x = ch-'0'; while (ch=getchar(), ch>='0'&&ch<='9') x = x*10+ch-'0'; if (minus) x = -x; } struct POINT { int l, r, id; bool operator < (const POINT &a) const { if (pos[l] != pos[a.l]) return l < a.l; return r > a.r; } }p[MAXM]; LL cur_ans, ans[MAXM], num[MAXN*3]; map<int, int> mp; int arr[MAXN*3], n, q, tmp[MAXN*3]; void update(int pos, int val) { cur_ans += val * num[arr[pos]-1]; cur_ans += val * num[arr[pos]+1]; num[arr[pos]] += val; } void solve() { int cl = 1, cr = 0; for (int i = 1; i <= q; i++) { for (; cr < p[i].r; cr++) update(cr+1, 1); for (; cr > p[i].r; cr--) update(cr, -1); for (; cl < p[i].l; cl++) update(cl, -1); for (; cl > p[i].l; cl--) update(cl-1, 1); ans[p[i].id] = cur_ans; } for (int i = 1; i <= q; i++) printf("%lld\n", ans[i]); } void handle() { sort(tmp+1, tmp+1+n); int len = unique(tmp+1, tmp+1+n)-tmp-1; int cnt = 0; mp[tmp[1]] = ++cnt; for (int i = 2; i <= len; i++) { if (tmp[i] - tmp[i-1] != 1) ++cnt; mp[tmp[i]] = ++cnt; } for (int i = 1; i <= n; i++) arr[i] = mp[arr[i]]; } int main() { //ROP; while (~scanf("%d%d", &n, &q)) { MS(num, 0); mp.clear(); cur_ans = 0; int block_size = sqrt(q); for (int i = 1; i <= n; i++) { in(arr[i]); tmp[i] = arr[i]; pos[i] = (i-1) / block_size + 1; } handle(); for (int i = 1; i <= q; i++) { in(p[i].l); in(p[i].r); p[i].id = i; } sort(p+1, p+1+q); solve(); } return 0; }
相关文章推荐
- hdu 4738 Caocao's Bridges 2013 ACM-ICPC杭州赛区网络赛 1001 双连通分量
- hdu 4750 2013 ACM/ICPC Asia Regional Nanjing Online 1003 并查集+离线操作
- hust 1626 Cutting rope
- HDU5117
- 1216: 斐波那契数列
- 1217: 打印沙漏
- 我的ACM-ICPC资源整理
- 2014 ACM-ICPC 亚洲地区赛 西安站小结
- hdu5007 ACM-ICPC 西安赛区网赛A题 水题
- HDU 1394 线段树求逆序数
- HDU 5239 Doom The 2015 ACM-ICPC China Shanghai Metropolitan Programming Contest
- HDU 5241 Friends (数学)
- HDU 3255 题解 线段树+扫描线
- HDU 1754 I Hate It(线段树单点替换/区间最值)
- Light 1003 - Drunk (拓扑排序)
- TopCoder SRM 659 Div2 Problem 500 - PublicTransit (思维)
- UVa 1529 - Clock (模拟)
- Codeforces 551C - GukiZ hates Boxes (二分 + 贪心)
- TopCoder SRM 660 Div2 Problem 1000 - Powerit (数论)
- UVa 10623 - Thinking Backward (平面图的欧拉公式)