1.http://blog.csdn.net/dyx404514/article/details/39122743

思路:题目意思很清楚了,这里只说思路。

设区间[L,R],区间长度为len=(R-L+1),设F[i]表示G(i,i)+G(i,i+1)+......G(i,R)。那么对于区间[L,R],询问的答案即为Ans[L,R]=F[L]+F[L+1]+......+F[R]。容易得到G[i,j]=Si-G(i+1,j),所以F[i]=(R-i+1)*Si-F[i+1]。即F[i]+F[i+1]=(R-i+1)*Si。

那么Ans[L,R]=len*SL+(len-2)*S(i+2)+.....SR(len为奇数)或

len*SL+(len-2)*(L+2)+......+2*S(R-1)(len为偶数)。

那么对于给定区间[L,R]的答案可以用线段树维护,我的线段树维护4个值,sum[0]表示区间中偶数位数的和,sum[1]表示区间中奇数位置的和,tsum[0]表示Ans[L+1,R],tsum[1]表示Ans[L,R]。

如区间[3,7]={2,3,4,5,6},那么sum[0]=3+5=8,sum[1]=2+4+6=12,tsum[0]=4*3+2*5=22,tsum[1]=5*2+3*4+1*6=28。对于区间长度为偶数的类似。

现在考虑合并两个区间,对于区间p,其左儿子为lson,右儿子为rson。sum[0],sum[1]很好合并,只需要考虑左儿子长度的奇偶性,既可以完成合并。对于tsum[0],其左部分(由左儿子的信息得到的部分)为左儿子的tsum[0]加上左儿子的sum[0]乘以右儿子的长度(自己推推就能知道)。右部分要根据左儿子长度的奇偶性来决定是右儿子的tsum[0]还是tsum[1]。对于tsum[1]也类似。

那么线段树部分就结束了。注意到题目中的数字区间是一个模式串重复无数次的一个无限长的串,那么所给的区间可能会横跨很多个模式串S,我们的线段树只是对于模式串S的线段树,那么对于超出一个模式串的部分不能只用线段树来解决。如果区间[L,R]横跨多个模式串,那么将区间L,R分成三部分,前缀pre,中间部分mid,后缀suf,前缀表示区间[L,R]第一个不完整的模式串(可为空),后缀表示最后一个不完整的模式串(可为空),中间部分为中间横跨的多个完整的模式串(可为空)。那么pre,suf可以用线段树求出,类似于区间合并的方法,这里不再赘述。设mid包括n个完整的模式串,suf的长度为Len。还是按照区间合并的思想,不过这里n可能很大,不能直接一个一个地合并,事实上可以推出来,具体公式请自己推吧,本人很懒。。。。

这里还有一个问题,如果模式串为奇数,那么合并的时候很烦人,要间隔地考虑,这里我将模式串扩大两倍,保证模式串为偶数,那么在求mid的值得时候就不需要考虑奇偶性了。但是如果将模式串扩大两倍的话,在修改操作的时候,一定要记住要修改两个位置(这里忘了WA了10+发。。。。。。)。恩,大概就是这样,下面是代码:(内存耗得飞起。。。。速度也比较慢~~)

#include <iostream>
#include <string.h>
#include <stdio.h>
#include <algorithm>
#define maxn 200010
#define mid ((t[p].l+t[p].r)>>1)
#define ls (p<<1)
#define rs (ls|1)
#define ll long long
#define mod 1000000007
using namespace std;
char st[maxn];
struct tree
{
ll l,r;
ll sum[2],tsum[2];
}t[maxn<<2];
void pushup(int p)
{
ll l=t[ls].r-t[ls].l+1;
ll r=t[rs].r-t[rs].l+1;
if(l%2)
{
t[p].sum[0]=(t[ls].sum[0]+t[rs].sum[1])%mod;
t[p].sum[1]=(t[ls].sum[1]+t[rs].sum[0])%mod;
t[p].tsum[0]=(t[ls].tsum[0]+r*t[ls].sum[0]%mod+t[rs].tsum[1])%mod;
t[p].tsum[1]=(t[ls].tsum[1]+r*t[ls].sum[1]%mod+t[rs].tsum[0])%mod;
}
else
{
t[p].sum[0]=(t[ls].sum[0]+t[rs].sum[0])%mod;
t[p].sum[1]=(t[ls].sum[1]+t[rs].sum[1])%mod;
t[p].tsum[0]=(t[ls].tsum[0]+r*t[ls].sum[0]%mod+t[rs].tsum[0])%mod;
t[p].tsum[1]=(t[ls].tsum[1]+r*t[ls].sum[1]%mod+t[rs].tsum[1])%mod;
}
}
void build(int p,int l,int r)
{
t[p].l=l,t[p].r=r;
t[p].sum[0]=t[p].sum[1]=t[p].tsum[0]=t[p].tsum[1]=0;
if(l==r)
{
t[p].sum[0]=t[p].tsum[0]=0;
t[p].sum[1]=t[p].tsum[1]=st[l]-'0';
return;
}
build(ls,l,mid);
build(rs,mid+1,r);
pushup(p);
}
void modify(int p,int po,ll d)
{
if(t[p].l==t[p].r)
{
t[p].sum[1]=t[p].tsum[1]=d;
return;
}
if(po>mid)
modify(rs,po,d);
else
modify(ls,po,d);
pushup(p);
}
tree query(int p,ll l,ll r)
{
tree tmp;
if(t[p].l==l&&t[p].r==r)
{
return t[p];
}
if(l>mid)
return query(rs,l,r);
else if(r<=mid)
return query(ls,l,r);
else
{
tree t1=query(ls,l,mid);
tree t2=query(rs,mid+1,r);
tmp.l=t1.l,tmp.r=t2.r;
ll l=t1.r-t1.l+1;
ll r=t2.r-t2.l+1;
if(l%2){
tmp.sum[0]=(t1.sum[0]+t2.sum[1])%mod;
tmp.sum[1]=(t1.sum[1]+t2.sum[0])%mod;
tmp.tsum[0]=(t1.tsum[0]+r*t1.sum[0]%mod+t2.tsum[1])%mod;
tmp.tsum[1]=(t1.tsum[1]+r*t1.sum[1]%mod+t2.tsum[0])%mod;
}
else{
tmp.sum[0]=(t1.sum[0]+t2.sum[0])%mod;
tmp.sum[1]=(t1.sum[1]+t2.sum[1])%mod;
tmp.tsum[0]=(t1.tsum[0]+r*t1.sum[0]%mod+t2.tsum[0])%mod;
tmp.tsum[1]=(t1.tsum[1]+r*t1.sum[1]%mod+t2.tsum[1])%mod;
}
return tmp;
}
}
ll getsum(ll num,ll len,ll left,int typ)
{
if(num==0)
return 0;
ll sum=0;
sum=num%mod*t[1].tsum[typ]%mod;
ll tt;
if(num%2)
tt=((num-1)/2)%mod*(num%mod);
else
tt=((num-1)%mod)*((num/2)%mod);
tt%=mod;
ll tmp=(num%mod*left%mod+tt*len%mod)%mod;
sum=(sum+tmp*t[1].sum[typ]%mod)%mod;
return sum;
}
int main()
{
// freopen("dd.txt","r",stdin);
int ncase;
scanf("%d",&ncase);
while(ncase--)
{
scanf("%s",st);
int len=strlen(st);
for(int i=0;i<len;i++)
{
st[i+len]=st[i];
}
len*=2;
build(1,0,len-1);
int q;
scanf("%d",&q);
while(q--){
int typ;
ll ans=0,l,r;
scanf("%d",&typ);
if(typ==1)
{
int x,d;
scanf("%d%d",&x,&d);
modify(1,x-1,d);
modify(1,x-1+(len/2),d);
}
else
{
scanf("%lld%lld",&l,&r);
l--,r--;
ll lpo=l/len,rpo=r/len;
ll L=l%len,R=r%len;
if(lpo==rpo)
{
ans=query(1,L,R).tsum[1];
}
else
{
ll Len=((r-l+1)-(len-L))%mod;
tree t1=query(1,L,len-1);
tree t2=query(1,0,R);
ans=(ans+t1.tsum[1]+Len*t1.sum[1]%mod)%mod;
if((len-L)%2)
ans=(ans+t2.tsum[0])%mod;
else
ans=(ans+t2.tsum[1])%mod;
if((len-L)%2)
ans=(ans+getsum(rpo-lpo-1,len,R+1,0))%mod;
else
ans=(ans+getsum(rpo-lpo-1,len,R+1,1))%mod;
}
printf("%lld\n",ans);
}
}
}
return 0;
}

2.

http://www.cnblogs.com/gj-Acit/p/3961971.html

给定序列P,定义序列S为P反复重复得到的一个无穷长的序列:

if P = 3423537, then S = 3423537342353734235373423537...

再定义G(lr) = Sl - Sl+1 + Sl+2 - ... + (-1)r-lSr

给两种操作:

1 x d:将序列P的第x想改为d(d是一个简单数字0~9)

2 l r  :求sum of G(ij) that l <= i <= j <= r.

比赛时看到这个题,以为是求G(l, r),然后就高高兴兴用线段树开始敲了,快敲完才知道是求对任意的l <= i <= j <= r,求G(i, j) 的和

比赛快完了才想到思路,没时间敲了,今天花了大半天时间终于A掉。

按照题目要求,求sum of G(ij) ,所以先把它化简,找下规律,很容易可以得到以下规律:

Sum{ G(i, j) } = (r - l + 1) * S[l]  + (r - l - 1) * S[l + 2] + (r - l - 3) * S[l + 4] + ... ...  + S[r]             (R-l+1)为奇数
                                                                                                                            + 2 * S[r-1]       (R-l+1)为偶数

注意上面相邻两项之间下标差都是2,由于不知道是需要用2*S[i] + 4*S[i-2]...  还是要用S[i] + 3*S[i-2]...,所以都保存起来

然后我们定义F[i][0] = S[i] + 3 * S[i-2] + 5 * S[i-4] +  ... ...

F[i][1] = 2 * S[i] + 4 * F[i-2] + 6 * F[i-4] +  ... ...

再定义P[i] = S[i] + S[i - 2] + S[i - 4] + ... ...

经过简单计算可以得出: 最后题目要求的Sum{ G(l, r) } = F[r] - F[l - 2] - k * P[l - 2]  (这里的F的第二维取决于(r-l+1)是奇还是偶,通过计算可以得到 令 len = (r - l + 1)  ,  那么 k = len + len % 2)  )

然后定义线段树节点:

 struct Node
{
int l, r;
LL P[], F[][];
}t[MAXN<<];

其中:
P[0] = S[r] + S[r - 2] + S[r - 4] + ... ... + S[k]   (k >= l)
P[0] = S[r-1] + S[r - 3] + S[r - 5] + ... ... + S[k]   (k >= l)

F[0][0] = S[r] + 3 * S[r - 2] + 5 * S[r - 4] + ... ... + x * S[k]  (k >= l)
F[0][1] = 2*S[r] + 4*S[r - 2] + 6*S[r - 4] + ... ... + x * S[k]  (k >= l)
F[1][0] = S[r-1] + 3 * S[r - 3] + 5 * S[r - 5] + ... ... + x * S[k]  (k >= l)
F[1][1] = 2*S[r-1] + 4*S[r - 3] + 6*S[r - 5] + ... ... + x * S[k]  (k >= l)

然后做线段树的单电修改,修改某个叶子节点后往上更新,  rc和lc对应于当前节点k的右子节点和左子节点,  len是rc节点的区间长度

     rep(i, , ) {
rep(j, , ) {
t[k].F[i][j] = ( t[rc].F[i][j] + t[lc].F[(len-i) & ][j]
+ t[lc].P[(len-i) & ] * (len-i + (len-i)%) ) % MOD;
}
t[k].P[i] = (t[rc].P[i] + t[lc].P[(len - i) & ]) % MOD;
}

接下来写两个查询,分别是查询[1, p]的P值, 和查询[1,p]的F值, flag用来标注是2,4,6,8... ... 还是 1, 3, 5, 7 ... ...增长

 LL query_pre(int k, int p)
{
if(t[k].l == t[k].r) return t[k].P[]; int mid = (t[k].l + t[k].r) >> ; if(p <= mid) return query_pre(k<<, p); int re = (p - mid);
return (t[k<<].P[re&] + query_pre(k<<|, p)) % MOD;
} LL query_F(int k, int p, int flag)
{
if(t[k].l == t[k].r) return t[k].F[][flag]; int mid = (t[k].l + t[k].r) >> ; if(p <= mid) return query_F(k<<, p, flag); int re = p - mid; return (t[k<<].F[re&][flag] + t[k<<].P[re&] * (re + re%) + query_F(k<<|, p, flag)) % MOD;
}

这样,在不考虑 l 和 r 大于给定序列长度n的情况下,原题已经可解,答案就是:

query_F(1, r) - query_F(1, l - 2) - query_Pre(1, l - 2) * (len + len % 2)        (其中len = r - l + 1)

然后再考虑l 和 r比较大的情况,由于虽然l 和 r 比较大,但是给定序列的长度是小于1e5的, 所以说显然中间过程是可以直接推算出来的, 事实上,设原序列长度为n, len = (r - l + 1), 那么最初给出的序列会出现 k = (len - 1) / n 次,而这 k 次序列可以看做是 出现了k次F[n],以及 出现了 a * P[n], (a + n) * P[n], (a + 2 n) * P[n]... ...(a + (k-1)*n) * P[n]

这正好是一个等差数列, 所以计算新的F[r] (r >> n)时, F[n] = query(r) + k * F[n] + P[n] * (a + (a + d) + (a + 2 * d) + ... ... + (a + (k-1) * d) ).

注意, 上面的等差数列首项a还未确定, 公差d也还未确定, 也就是说,只要计算出a 和 d, 就计算出了我们的要求的答案。

注意到如果n(原序列长度)是偶数,又因为增量是2,所以可以计算出公差 d = n,而首项 a = p + p % 2  , 其中p = (r - 1) % n + 1,也就是最后一个剩下序列的长度

如果n是奇数,会出现有时我们需要的是F[n], 有时需要的又是F[n-1],这是只要理解为两个等差数列就可以了,其中公差都是d = 2 * n, 但是首项不同

代码还有很多需要注意的小细节,很多地方需要反复计算(比如那两个等差数列),反正就是比较麻烦

 #include <map>
#include <set>
#include <stack>
#include <queue>
#include <cmath>
#include <ctime>
#include <vector>
#include <cstdio>
#include <cctype>
#include <cstring>
#include <cstdlib>
#include <iostream>
#include <algorithm>
using namespace std;
#define INF 1e9
#define inf (-((LL)1<<40))
#define lson k<<1, L, mid
#define rson k<<1|1, mid+1, R
#define mem0(a) memset(a,0,sizeof(a))
#define mem1(a) memset(a,-1,sizeof(a))
#define mem(a, b) memset(a, b, sizeof(a))
#define FOPENIN(IN) freopen(IN, "r", stdin)
#define FOPENOUT(OUT) freopen(OUT, "w", stdout)
#define rep(i, a, b) for(int i = a; i <= b; i ++)
template<class T> T CMP_MIN(T a, T b) { return a < b; }
template<class T> T CMP_MAX(T a, T b) { return a > b; }
template<class T> T MAX(T a, T b) { return a > b ? a : b; }
template<class T> T MIN(T a, T b) { return a < b ? a : b; }
template<class T> T GCD(T a, T b) { return b ? GCD(b, a%b) : a; }
template<class T> T LCM(T a, T b) { return a / GCD(a,b) * b; } //typedef __int64 LL;
typedef long long LL;
const int MAXN = ;
const int MAXM = ;
const double eps = 1e-;
const LL MOD = ; struct Node
{ // P[0] = S[r] + S[r-2] + S[r-4]... P[1] = S[r-1] + S[r-3] + S[r-5] + ...
int l, r;//F[0][0] = S[r] + 3 * S[r-2] + ... F[0][1] = 2 * S[r] + 4 * S[r-2] + ...
LL P[], F[][];// F[1][0] = S[r-1] + 3 * S[r - 3] + ... F[1][1] = 2 * S[r-1] + 4 * S[r-3] + ...
}t[MAXN<<];
int n, cas, q;
char str[]; //建树
void build(int k, int L, int R)
{
t[k].l = L;
t[k].r = R;
t[k].P[] = t[k].P[] = ;//P和F统统初始化为0
rep (i, , ) rep(j, , )
t[k].F[i][j] = ;
if(L == R) return ; int mid = (R + L) >> ;
build(k<<, L, mid);
build(k<<|, mid + , R);
} //从子节点更新父节点
void push_up(int k)
{
int lc = k<<, rc = k<<|;
int re = t[rc].r - t[rc].l + ;//右侧节点长度
rep(i, , ) {
rep(j, , ) {
if(re== && i==) {//特殊处理右侧只有一个节点的情况
t[k].F[i][j] = t[lc].F[][j];
continue;
}
t[k].F[i][j] = ( t[rc].F[i][j] + t[lc].F[(re-i) & ][j]
+ t[lc].P[(re-i) & ] * (re-i + (re-i)%) ) % MOD;
}
t[k].P[i] = (t[rc].P[i] + t[lc].P[(re - i) & ]) % MOD;
}
} //将位置为p的节点更新为val
void update(int k, int p, int val)
{
if(t[k].l == t[k].r) {
t[k].P[] = t[k].F[][] = val;
t[k].F[][] = * val;
return;
}
int m = (t[k].l + t[k].r) >> ; if(p <= m) update(k<<, p, val); else update(k<<|, p, val); push_up(k);
} LL query_pre(int k, int p)//询问S[p] + S[p-2] + ...
{
if(t[k].l == t[k].r) return t[k].P[]; int mid = (t[k].l + t[k].r) >> ; if(p <= mid) return query_pre(k<<, p); int re = (p - mid);
return (t[k<<].P[re&] + query_pre(k<<|, p)) % MOD;
} LL query_F(int k, int p, int flag)//询问F[p][flag] + F[p-2][flag] + ...
{
if(t[k].l == t[k].r) return t[k].F[][flag]; int mid = (t[k].l + t[k].r) >> ; if(p <= mid) return query_F(k<<, p, flag); int re = p - mid; return (t[k<<].F[re&][flag] + t[k<<].P[re&] * (re + re%) + query_F(k<<|, p, flag)) % MOD;
} LL get_mul(LL fir, LL d, LL k)//计算首项为fir,公差为d,项数为k的等差数列和
{
LL tmp1 = (k % MOD) * (fir % MOD) % MOD;
LL tmp2 = k;
if( k % == )
tmp2 = k / % MOD * ((k-) % MOD) % MOD;
else
tmp2 = k % MOD * ((k-) / % MOD) % MOD;
tmp2 = tmp2 * (d % MOD) % MOD;
return (tmp1 + tmp2) % MOD;
} //计算F[p][flag] + F[p-2][flag] + ... ...(这里p >> n)
LL get_F(LL p, LL flag)
{
LL k = (p - ) / n;
p = (p - ) % n + ;
LL ans = query_F(, p, flag);
if(n % == && k > ) {//这里n是偶数,只有一个等差数列
ans = (ans + k % MOD * t[].F[p&][flag] ) % MOD;
//首项为p + p%2, 公差为n, 项数为k
ans = (ans + get_mul(p + p % , n, k) * t[].P[p&] % MOD) % MOD;
}
else if(n % == && k > ) {//n是奇数,会存在两个等差数列
LL tmp = p % ? - : ; ans = (ans + (k+)/ % MOD * t[].F[p&][flag]) % MOD; ans = (ans + k/ % MOD * t[].F[!(p&)][flag]) % MOD; ans = (ans + get_mul(p + p%, n*, (k+)/) * t[].P[p&] % MOD) % MOD; ans = (ans + get_mul(p + p% + n + tmp, n*, k/) * t[].P[!(p&)] % MOD) % MOD;
}
return ans;
} //拿到P[p] + P[p-2] + P[p-4] + ... ... (p >> n)
LL get_P(LL p)
{
LL k = (p - ) / n;
p = (p - ) % n + ;
LL ans = query_pre(, p);
if(n % == && k > ) {
ans = (ans + k % MOD * t[].P[p&]) % MOD;
}
else if(n % == && k > ) {
ans = (ans + (k+)/ % MOD * t[].P[p&]) % MOD; ans = (ans + k/ % MOD * t[].P[!(p&)]) % MOD;
}
return ans;
} int main()
{
freopen("in.txt", "r", stdin);
//freopen("out.txt", "w", stdout);
scanf("%d%*c", &cas);
while(cas--)
{
LL a, b, c;
gets(str);
build(, , n=strlen(str));
for(int i = ; i < n; i ++)
update(, i + , str[i] - '');
scanf("%d", &q);
while(q--) {
scanf("%lld %lld %lld%*c", &a, &b, &c);
if(a == ) update(, (int)b, (int)c);
else {
LL rf = , lf = , lp = ;
LL len = (c - b + ), tmp = (len & ^ );
rf = get_F( c - tmp, tmp );
if(b > ) {
lf = get_F( b-, tmp );
lp = get_P( b- );
}
//计算节结果
LL ans = ((rf - lf - (len + len%) % MOD * lp) % MOD + MOD) % MOD;
printf("%lld\n", ans);
}
}
}
return ;
}

3.

http://blog.csdn.net/wondezy/article/details/39164217

解题思路:对于询问[L,R]只有2种情况:1.在一段中 2.L,R分别在两段中,中间有若干段

第一步:

那么我们先处理原串P的情况。

在纸上写一下,容易发现,G(l,r)只有奇数项

且G(l,r)=a[l]*(r-l+1)+a[l+2]*(r-l-1)+....=sigma(a[x]*(r-x+1))=(r+1)*sigma(a[x])-sigma(a[x]*x)

那么,我们用树状数组维护a[x]和a[x]*x两个前缀和,修改就是单点修改。

但是,偶数项和并不是不用了,如果前面有一段是奇数,后面就要用到偶数项和

所以要维护奇数偶数项前缀的4个数组。

第二步:

我们已经知道原串P的任意一个区间的答案

如果有2个P长度的串,且P的长度为奇数,那么整个区间的答案就应该是第一个P的奇数项前缀和+第二个P的偶数项前缀和+第一个P的奇数项的偏移量(奇数项和*P)

我们在处理P的时候,就计算2*P长度的前缀和,这样对于中间的段都是以2*P分段的

我们设[L,R]被分成[ml,len],n个2*P,1或0个P,[1,mr]这几段,ml,mr为段内下标

[ml,len]的部分很好算就是原来的值加上偏移量

然后[1,mr]部分就是原来的值

设k为中间P的段数

n个2*P的部分为原来n个2*P的前缀和+偏移量

偏移量是2*P的前缀和(奇数项还是偶数项要看[L,len]的奇偶)*{sigma((k-2*b)*len+mr) ,b属于[1,n]}

如果还有剩下的P,再加上P的值和偏移量

第三步:

额,没了

#include <iostream>
#include <cstdio>
#include <cstring>
#define maxn 100010
#define ll long long
#define mod 1000000007
using namespace std;
int t,ls;
char s[maxn];
int v[maxn<<1];
ll a[2][maxn<<1],b[2][maxn<<1];
void add(int t,int c,int d){
for(int x=c;x<=2*ls;x+=x&(-x)){
a[t][x]+=c*d,b[t][x]+=d;
a[t][x]%=mod,b[t][x]%=mod;
}
}
ll ask(ll *c,int x){
ll ret=0;
for(;x;x-=x&(-x)) ret+=c[x],ret%=mod;
return ret;
}
void read(){
scanf("%s",s+1);
ls=strlen(s+1);
for(int i=1;i<=ls;i++) v[i]=s[i]-'0';
for(int i=ls+1;i<=2*ls;i++) v[i]=v[i-ls];
memset(a,0,sizeof a);
memset(b,0,sizeof b);
for(int i=1;i<=2*ls;i++) add(i&1,i,v[i]);
}
ll calc(int t,ll ml,ll mr){
ll ret=((mr+1)*(ask(b[t],mr)-ask(b[t],ml-1)))%mod-(ask(a[t],mr)-ask(a[t],ml-1))%mod;
return ret%mod;
}
void solve(){
int q,T,x,d;
ll l,r;
scanf("%d",&q);
for(int i=0;i<q;i++){
scanf("%d",&T);
if(T==1){
scanf("%d%d",&x,&d);
add(x&1,x,-v[x]);
add(x&1,x,d);
add((x+ls)&1,x+ls,-v[x]);
add((x+ls)&1,x+ls,d);
v[x]=d;
}else{
scanf("%lld%lld",&l,&r);
ll kl=(l+ls-1)/ls,kr=(r+ls-1)/ls;
ll ml=l-(kl-1)*ls,mr=r-(kr-1)*ls;
ll ret=0;
ll kk=kr-kl-1,rr,sum;
if(kl==kr){
ret=calc(ml&1,ml,mr);
}else{
ret=calc(ml&1,ml,ls);
ret=(ret+(ask(b[ml&1],ls)-ask(b[ml&1],ml-1))*(ls*(kk%mod)%mod+mr)%mod)%mod;
sum=ask(b[1^((ls-ml+1)&1)],2*ls);
ll bb=kk/2;
if(bb>=1){
bb%=mod;
ret=(ret+calc(1^((ls-ml+1)&1),1,2*ls)*bb%mod)%mod;
ret=(ret+sum*( (mr+kk%mod*ls%mod)*bb%mod-bb*(bb+1)%mod*ls%mod )%mod)%mod;
}
if(kk&1){
ret=(ret+calc(1^((ls-ml+1)&1),1,ls))%mod;
ret=(ret+ask(b[1^((ls-ml+1)&1)],ls)*mr%mod)%mod;
}
rr=ls-ml+1+ls*kk;
ret=(ret+calc(1^(rr&1),1,mr))%mod;
}
ret=(ret%mod+mod)%mod;
printf("%lld\n",ret);
}
}
}
int main(){
scanf("%d",&t);
for(int ca=1;ca<=t;ca++){
read();
solve();
}
return 0;
}

zoj 3813 Alternating Sum(2014ACMICPC Regional 牡丹江站网络赛 E)的更多相关文章

  1. 2019-ACM-ICPC-徐州站网络赛-M.Longest subsequence-从字符串s中找到一个最长子序列,使得其字典序严格大于t

    2019-ACM-ICPC-徐州站网络赛-M.Longest subsequence-从字符串s中找到一个最长子序列,使得其字典序严格大于t [Problem Description] ​ 从字符串\ ...

  2. 2019-ACM-ICPC-徐州站网络赛- I. query-二维偏序+树状数组

    2019-ACM-ICPC-徐州站网络赛- I. query-二维偏序+树状数组 [Problem Description] ​ 给你一个\([1,n]\)的排列,查询\([l,r]\)区间内有多少对 ...

  3. 2014ACM/ICPC亚洲区域赛牡丹江站现场赛-A ( ZOJ 3819 ) Average Score

    Average Score Time Limit: 2 Seconds      Memory Limit: 65536 KB Bob is a freshman in Marjar Universi ...

  4. 2014ACM/ICPC亚洲区域赛牡丹江站现场赛-I ( ZOJ 3827 ) Information Entropy

    Information Entropy Time Limit: 2 Seconds      Memory Limit: 65536 KB      Special Judge Information ...

  5. 2014ACM/ICPC亚洲区域赛牡丹江站现场赛-K ( ZOJ 3829 ) Known Notation

    Known Notation Time Limit: 2 Seconds      Memory Limit: 65536 KB Do you know reverse Polish notation ...

  6. zoj 3822 Domination 概率dp 2014牡丹江站D题

    Domination Time Limit: 8 Seconds      Memory Limit: 131072 KB      Special Judge Edward is the headm ...

  7. ZOJ 3810 A Volcanic Island (2014年牡丹江赛区网络赛B题)

    1.题目描写叙述:点击打开链接 2.解题思路:本题是四色定理的模板题.只是有几种情况要提前特判一下:n==1直接输出,1<n<5时候无解,n==6时候套用模板会出现同样的块.因此要特判一下 ...

  8. ZOJ 3811 / 2014 牡丹江赛区网络赛 C. Untrusted Patrol bfs/dfs/并查集

    Untrusted Patrol Time Limit: 3 Seconds                                     Memory Limit: 65536 KB    ...

  9. ZOJ 3814 Sawtooth Puzzle (2014年牡丹江赛区网络赛F题)

    1.题目描写叙述:点击打开链接 2.解题思路:本题是一道隐式图的搜索题目.一般来说,这类题目首先要定义状态,接下来是弄清楚状态怎样转移,以及状态怎样判重,怎样推断当前状态是否和目标状态同样.至于求解最 ...

随机推荐

  1. 全国天气预报数据API调用PHP示例

    本代码示例是基于PHP的聚合数据全国天气预报API服务请求的代码样例,使用前你需要: ①:通过https://www.juhe.cn/docs/api/id/39 申请一个天气预报API的appkey ...

  2. 【Python】matplotlib绘制折线图

    一.绘制简单的折线图 import matplotlib.pyplot as plt squares=[1,4,9,16,25] plt.plot(squares) plt.show() 我们首先导入 ...

  3. OpenReadWithHttps

    ///<summary>///采用https协议访问网络///</summary>///<param name="URL">url地址</ ...

  4. typedef,结构体,共用体,联合体

    typedef的用途: 封装数据类型,方便移植 简化函数指针的定义 watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvdG90b3R1enVvcXVhbg==/ ...

  5. flash插件使用外部数据的方法

    使用xml保存需要改变的数据,如轮播图的图片路径,也可以在xml中指定数据库地址等

  6. 现在有一张半径为r的圆桌,其中心位于(x,y),现在他想把圆桌的中心移到(x1,y1)。每次移动一步,都必须在圆桌边缘固定一个点然后将圆桌绕这个点旋转。问最少需要移动几步。

    // ConsoleApplication5.cpp : 定义控制台应用程序的入口点. // #include "stdafx.h" #include<vector> ...

  7. php通过curl下载远程图片实例

    <?php $url = 'http://mf1905.com/upload/video_img/df3074c98ec5124ad47c52ff59f74e04_middle.jpeg'; f ...

  8. Volley框架载入网络图片

    Android开发中,载入网络server的图片是非经常常使用的.当然我们能够自己写server接口去实现,只是要做到server性能 优越的话,开发起来比較麻烦点.所以本博客要介绍Volley框架进 ...

  9. 必会必知git

    git必会必知   1 前言 git前身是BitKeeper,但是他不是开源软件,不符合当时开源趋势,于是就会有了开源的git,git开发只用了十天时间.目前git是公司开发必不可少的一个工具,用于多 ...

  10. golang中并发sync和channel

    golang中实现并发非常简单,只需在需要并发的函数前面添加关键字"go",但是如何处理go并发机制中不同goroutine之间的同步与通信,golang 中提供了sync包和channel ...