2016 UESTC Training for Data Structures P - 浑身难受 CDOJ 1276 树状数组

来源:互联网 发布:如何设置三级域名 编辑:程序博客网 时间:2024/05/01 17:00

P - 浑身难受

mayacamp上搬来的神题,作为一名智障

一共二十四种情况,然后每种倒序一下可以得到另外一种,所以可以简化成12种,然后我这个智障就写了十二种,

首先分为3类,

1,  14不相连,就n^2枚举23的位置,然后14的所在的区间用按值树状数组维护,1那里就是查询区间有多少比个比2小的值,4那里就是查询有多少个比3大的值(总点数减去<=3的就是啦),然后乘一下就可以

2,  13不相连,就n^2枚举24的位置,然后13的所在的区间用按值树状数组维护,1那里就是查询区间有多少比个比2小的值,3那里就是查询有多少个比4小的减去有多少个比3小的,然后乘一下就可以

3,  24不连在一起,把序列翻转一下,就是A[i]=5-A[i]p[i]=N+1-p[i],翻转完之后就是13不连在一起,然后就可以用2来做了

 

4,  2413,这种题解写的是2413=24xx-2411-2433-2431,一开始没想明白,然后我就枚举34做的,然后21那里就分别统计比3小的有多少个,因为两数不可能相等,所以要么就是1423,要么就是2413,然后算出来之后,减去1423,就是2413的个数

后来想明白了题解的做法,主要题解提到了24332411,一开始以为是0,后来发现不是033表示两个数都在24之间,11表示两个数都比2

具体做法就是枚举24的位置,固定24之后,要枚举13,因为只知道13都比4小,然后分为三种情况 (实际上是4种)

1,枚举的两个数都比2小,这个你是能算出来的,相当于2411

2,枚举的两个数都在24之间,这个也是能算出来的,相当于2433

3,枚举的两个数,一个比2小,一个在24之间,这个相当于是2413+2431

所以2413=24xx-2411-2433-2431

 

这题,真是做的浑身难受,300行代码怼过去了


代码:

#include <iostream>#include <cstdio>#include <cstdlib>#include <cstring>#include <cmath>#include <algorithm>using namespace std;#define ll long long#define maxn 2005int N, A[4], p[maxn];int BIT1[maxn], BIT2[maxn];ll query(int tree[], int i){ll sum = 0;while (i){sum += tree[i];i -= i&(-i);}return sum;}void update(int tree[], int i, int val){if (i == 0)return;while (i <= N){tree[i] += val;i += i&(-i);}}ll No1234()//枚举23位置{ll sum = 0;for (int i = 2; i <= N - 2; ++i)//i是2,j是3{update(BIT1, p[i - 1], 1);memset(BIT2, 0, sizeof(int)*maxn);for (int j = N - 1; j >= i + 1; --j){update(BIT2, p[j + 1], 1);if (p[i] < p[j])sum += query(BIT1, p[i])*(N - j - query(BIT2, p[j]));}}return sum;}ll No1243()//枚举23位置{ll sum = 0;for (int i = 2; i <= N - 2; ++i)//i是2,j是3{update(BIT1, p[i - 1], 1);memset(BIT2, 0, sizeof(int)*maxn);for (int j = i + 2; j <= N; ++j){update(BIT2, p[j - 1], 1);if (p[i] < p[j])sum += query(BIT1, p[i])*(j - i - 1 - query(BIT2, p[j]));}}return sum;}ll No1324()//枚举23位置{ll sum = 0;for (int i = 2; i <= N - 2; ++i)//i是3,j是2{update(BIT1, p[i - 1], 1);memset(BIT2, 0, sizeof(int)*maxn);for (int j = N - 1; j >= i + 1; --j){update(BIT2, p[j + 1], 1);if (p[i] > p[j])sum += (N - j - query(BIT2, p[i]))*query(BIT1, p[j]);}}return sum;}ll No1342()//枚举23位置{ll sum = 0;for (int i = 2; i <= N - 2; ++i)//i是3,j是2{update(BIT1, p[i - 1], 1);memset(BIT2, 0, sizeof(int)*maxn);for (int j = i + 2; j <= N; ++j){update(BIT2, p[j - 1], 1);if (p[i] > p[j])sum += query(BIT1, p[j])*(j - i - 1 - query(BIT2, p[i]));}}return sum;}ll No1423()//枚举24位置{ll sum = 0;for (int i = 2; i <= N - 2; ++i)//i是4,j是2{update(BIT1, p[i - 1], 1);memset(BIT2, 0, sizeof(int)*maxn);for (int j = N - 1; j >= i + 1; --j){update(BIT2, p[j + 1], 1);if (p[i] > p[j])sum += query(BIT1, p[j])*(query(BIT2, p[i]) - query(BIT2, p[j]));}}return sum;}ll No1432()//枚举24位置{ll sum = 0;for (int i = 2; i <= N - 2; ++i)//i是4,j是2{update(BIT1, p[i - 1], 1);memset(BIT2, 0, sizeof(int)*maxn);for (int j = i + 2; j <= N; ++j){update(BIT2, p[j - 1], 1);if (p[i] > p[j]){sum += query(BIT1, p[j])*(query(BIT2, p[i]) - query(BIT2, p[j]));}}}return sum;}ll No2134()//枚举23位置{ll sum = 0;for (int i = N - 1; i >= 3; --i)//i是3,j是2{update(BIT1, p[i + 1], 1);memset(BIT2, 0, sizeof(int)*maxn);for (int j = i - 2; j >= 1; --j){update(BIT2, p[j + 1], 1);if (p[i] > p[j])sum += (N - i - query(BIT1, p[i]))*query(BIT2, p[j]);}}return sum;}ll No2143()//枚举24位置{ll sum = 0;for (int i = N - 1; i >= 3; --i)//i是4,j是2{update(BIT1, p[i + 1], 1);memset(BIT2, 0, sizeof(int)*maxn);for (int j = i - 2; j >= 1; --j){update(BIT2, p[j + 1], 1);if (p[i] > p[j])sum += (query(BIT1, p[i]) - query(BIT1, p[j])) * query(BIT2, p[j]);}}return sum;}ll No2314()//先翻转,再枚举24位置{//翻转后是3241,再倒序一下,是1423ll sum = 0;for (int i = 1; i <= N; ++i)p[i] = N + 1 - p[i];for (int i = 1; i <= N / 2; ++i){int t;t = p[i];p[i] = p[N + 1 - i];p[N + 1 - i] = t;}sum = No1423();return sum;}ll No2413()//暴力枚举3和4,树状数组维护1和2的数,x4x3-1423=2413{ll sum = 0;for (int i = 2; i <= N - 2; ++i)//i是4,j是3{update(BIT1, p[i - 1], 1);memset(BIT2, 0, sizeof(int)*maxn);for (int j = i + 2; j <= N; ++j){update(BIT2, p[j - 1], 1);if (p[i] > p[j]){sum += query(BIT1, p[j])*query(BIT2, p[j]);}}}memset(BIT1, 0, sizeof(int)*maxn);memset(BIT2, 0, sizeof(int)*maxn);sum -= No1423();return sum;}ll No3124()//枚举2和3的位置{ll sum = 0;for (int i = N - 1; i >= 3; --i)//i是2,j是3{update(BIT1, p[i + 1], 1);memset(BIT2, 0, sizeof(int)*maxn);for (int j = i - 2; j >= 1; --j){update(BIT2, p[j + 1], 1);if (p[j] > p[i])sum += (N - i - query(BIT1, p[j]))*query(BIT2, p[i]);}}return sum;}ll No3214()//枚举2和4的位置{ll sum = 0;for (int i = 2; i <= N - 2; ++i)//i是2,j是4{update(BIT1, p[i - 1], 1);memset(BIT2, 0, sizeof(int)*maxn);for (int j = i + 2; j <= N; ++j){update(BIT2, p[j - 1], 1);if (p[i] < p[j])sum += (query(BIT1, p[j]) - query(BIT1, p[i]))*query(BIT2, p[i]);}}return sum;}void deal_A(){int x = A[0] * 1000 + A[1] * 100 + A[2] * 10 + A[3];if (x == 2341 || x == 2431 || x == 3142 || x == 3241 || x == 3412 || x == 3421 || x == 4123 || x == 4132 || x == 4213 || x == 4231 || x == 4312 || x == 4321){int t;t = A[0];A[0] = A[3];A[3] = t;t = A[1];A[1] = A[2];A[2] = t;for (int i = 1; i <= N / 2; ++i){t = p[i];p[i] = p[N + 1 - i];p[N + 1 - i] = t;}}}ll compute(){int x = A[0] * 1000 + A[1] * 100 + A[2] * 10 + A[3];if (x == 1234)return No1234();if (x == 1243)return No1243();if (x == 1324)return No1324();if (x == 1342)return No1342();if (x == 1423)return No1423();if (x == 1432)return No1432();if (x == 2134)return No2134();if (x == 2143)return No2143();if (x == 2314)return No2314();if (x == 2413)return No2413();if (x == 3124)return No3124();if (x == 3214)return No3214();return -1;}int main(){//freopen("input.txt", "r", stdin);scanf("%d", &N);for (int i = 0; i < 4; ++i)scanf("%d", &A[i]);for (int i = 1; i <= N; ++i)scanf("%d", &p[i]);if (N < 4)printf("0\n");else{deal_A();ll ans = compute();printf("%lld\n", ans);}//system("pause");//while (1);return 0;}

0 0
原创粉丝点击