长春网络赛A A Simple Problem with Integers

来源:互联网 发布:vb安装包下载 编辑:程序博客网 时间:2024/04/20 06:58

  这个题目在比赛的时候我用建立55个线段树做出来了,但赛后感觉太硬碰硬了,重新做一下,按照节点中的55个情况分析空间:

 每个空间节点有 除数qq (10 种)和 余数pp(第i个除数有i种) ,总共55种, 因为有个结论,某个数是否加上c,只要看这个数%qq的余数跟pp是否一样,如果一样他就符合条件; 

根据这个原理组成线段树



但有个问题我十分不解,根据自己的推导,线段树的节点数最多是2*n - 1; 所以线段树开2*n 个节点绝对够用,但在杭电上提交了3个小时38次都是空间溢出,但开3*n就过了,真的快疯了,希望有大神指点。


#include<stdio.h>
#include<string.h>
#include <algorithm>
#include <math.h>


#define MAX 50011
int array[MAX], n;
int query[MAX][5], q;


struct Node
{
int l, r;
int operate[55];
}node[MAX * 3];   //开MAX * 2空间溢出,求指点


int build(int left, int right, int pre)
{
node[pre].l = left;
node[pre].r = right;
memset(node[pre].operate, 0, sizeof(node[pre].operate));


if(left == right)
return 0;


int mid = (left + right) / 2;
build(left, mid, pre * 2);
build(mid + 1, right, pre * 2 + 1);
return 0;


}


int init()
{
int i;
if(scanf("%d", &n) == EOF)
return 0;
// n = rand() % 50000 + 1;
for(i = 1; i <= n; i ++)
{
scanf("%d", &array[i]);
// array[i] = rand() % 10000001 * pow(-1, rand() % 2);
}




scanf("%d", &q);
// q = rand() % 50000 + 1;
for(i = 1; i <= q; i ++)
{
scanf("%d", &query[i][0]);
// query[i][0] = rand() % 2 + 1;
if(query[i][0] == 1)
{
scanf("%d%d%d%d", &query[i][1], &query[i][2], &query[i][3], &query[i][4]);
// query[i][1] = rand() % n + 1;
// query[i][2] = rand() % (n - query[i][1] + 1) + query[i][1];
// query[i][3] = rand() % 10 + 1;
// query[i][4] = rand() % 1001 * pow(-1, rand() % 2);
}
else
{
scanf("%d", &query[i][1]);
// query[i][1] = rand() % n + 1;
}
}


build(1, n, 1);
return 1;
}


int set(int a, int b, int pre, int queryNum)
{
if(a == node[pre].l && b == node[pre].r)
{
int qq = query[queryNum][3];
int pp = query[queryNum][1] % qq;
node[pre].operate[qq * (qq - 1) / 2 + pp] += query[queryNum][4];
return 0;
}


if(b <= (node[pre].l + node[pre].r) / 2)
{
set(a, b, pre * 2, queryNum);
}
else if(a > (node[pre].l + node[pre].r) / 2)
{
set(a, b, pre * 2 + 1, queryNum);
}
else
{
set(a, (node[pre].l + node[pre].r) / 2, pre * 2, queryNum);
set((node[pre].l + node[pre].r) / 2 + 1, b, pre * 2 + 1, queryNum);
}


return 0;
}


int get(int x, int pre)
{
int i;
int result = 0;
for(i = 1; i <= 10; i ++)
{
result += node[pre].operate[(i - 1) * i / 2 + x % i];
}
return result;
}


int count(int x, int pre)
{
int xxx = get(x, pre);
if(node[pre].l == node[pre].r)
return xxx;
if(x <= (node[pre].l + node[pre].r) / 2)
{
return  xxx + count(x, pre * 2);
}
return xxx + count(x, pre * 2 + 1);
}


int run()
{
int i;
for(i = 1; i <= q; i ++)
{
if(query[i][0] == 1)
{
set(query[i][1], query[i][2], 1, i);
}
else
{
printf("%d\n", count(query[i][1], 1) + array[query[i][1]]);
}
}
return 0;
}
int main()
{
while(init())
{
run();
}
return 1;
}

原创粉丝点击