ZJU/ZOJ Deque and Balls 3929 计数:小的情况对总情况的贡献。 小心mod运算陷阱

比赛时候没过。。赛后写完程序题目没进题库。。


对拍了数据,感觉过了……过了几天一交,我日?!WA了? 



然后发现关于大数mod的问题,运算中树状数组没有进行mod运算,同时输出了负数。。因为某些关于mod运算的地方没处理。。。



题目要点:一个数字对总答案的贡献! 这个角度来思考问题!


代码很丑,相比其他人的代码。。



#include <cstdio>
#include <iostream>
#include <cstring>
#include <cstdlib>
#include <vector>
#include <algorithm>
using namespace std;

#define LL long long
const int maxn = 100000 + 100;
LL a[maxn];
const LL mod = 1000000007;

inline LL getnum()
{
	LL ans = 0;
	char tmp;
	while (1)
	{
		tmp = getchar();
		if ( '0' <=tmp  && tmp <='9')	break;
	}
	ans = tmp -'0';
	while (1)
	{
		tmp = getchar();
		if ( '0' <=tmp  && tmp <='9')	
		{
			ans = ans * 10 + tmp - '0';
			continue;
		}
		break;
	}
	return ans;
}

#define lowbit(k) ((k)&(-k))

LL g[maxn];
LL er[maxn]={1ll};

LL n;

LL getsum(LL k)
{
	LL ret = 0;
	while (k)
	{
		ret = (ret + g[k]) % mod;
		k -= lowbit(k);
	}
	return ret;
}

inline void add(LL k, LL arg)
{
	while (k <= n)
	{
		g[k] = (arg + g[k]) % mod;
		k += lowbit(k);
	}
}

inline void init()
{
	n = getnum();
	memset(g, 0, sizeof(g));
	for (int i = 0; i != n; ++ i)	a[i] = getnum();
}

void doit()
{
	LL ans = 0;
	//塞前面的方案
	add(a[0], 2);
	for (int i = 1; i != n; ++ i)
	{
		LL tmp = getsum(a[i] - 1);
		ans = (ans + tmp * er[n - i - 1]) % mod ;
		tmp = (getsum(n) - getsum(a[i]) + mod) % mod;
		ans = (ans + tmp * er[n - i - 1]) % mod ;
		add(a[i], er[i]);
	}
	printf("%lld\n", ans % mod);
}

int main()
{

	for (LL i = 1; i <= 100000; ++ i)
		er[i] = (er[i - 1] * 2) % mod;
	LL sb;
	sb = getnum();
	while (sb--)
	{
		init();
		doit();
	}
	return 0;
}

/*
100
10
1 7 5 9 3 9 1 3 8 3

*/


你可能感兴趣的:(ZJU/ZOJ Deque and Balls 3929 计数:小的情况对总情况的贡献。 小心mod运算陷阱)