这道题大家都用莫队算法做的,如果一直[l,r],就能很快的求出[l+1,r],[l,r+1],[l-1,r]和[l,r-1],那么就可以用莫队算法。
如果下次需要莫队算法,需要修改的就是从[l,r]推出[l+1,r],[l,r+1],[l-1,r]和[l,r-1]这一块。针对不同题不同分析,其他地方大概相同。
代码参考自:http://blog.csdn.net/firenet1/article/details/47616365
其实,我觉得最酷的莫过于
说好的图片呢?只能这样了http://www.zhihu.com/question/24201454
(2015.10.4:今天才发现不是博客的问题,是自己不会上传图片的问题,还以为只要复制粘贴,就可以万事大吉,接着这个机会,由默念了一遍莫队算法大法好)
(今天早上吃的茄子馅的包子,一直听说辣,就没吃,但是今天去买的时候,没有牛肉馅的,又见很多人都买茄子馅的,想着虽然辣,味道应该不错吧,就尝试了一下,嗯,真的很好吃,辣度竟然在我能接受的范围内)
2015.8.29:
再看这道题的时候,想起了是用莫队算法,根据记忆中的小片断一点一点推出来,但是,记忆中错误的当成了a.l%length,想着这样明显不省力呀,为什么还那么快,结果看了代码以后,发现是/,这样就能解释通了。
(学校的排骨汤开卖了,土豆和香菇的还是很好吃,而且,肉比上学期要好吃的感觉,不知道是不是太久没吃到,这个月吃了好多呀,开学后得省钱了,没办法,恩格尔系数太大,得降降了。)
#include
#include
#include
#include
using namespace std;
#define N 10010
struct node{
int l;
int r;
int id;
};
struct sign{
int g;
int num;
sign(int tempg=0,int tempnum=0){
g=tempg;
num=tempnum;
}
};
int numa[N];
long long int ansa[N];
struct node querya[N];
int length;
vector rrgcd,rlgcd,llgcd,lrgcd;
bool cmp(struct node a,struct node b){
if(a.l/length==b.l/length){
return a.r=querya[i].l;LR--){
for(int j=0;j
还有我自己看了题解和别人写的,没用莫对算法,我感觉能过,但是tle了。
#include
#include
#include
using namespace std;
#define N 10010
#define M 510
int num[N];
int gr[N][M];
int gcdnum[N][M];
int gcd(int a,int b){
int c;
while(b){
c=a%b;
a=b;
b=c;
}
return a;
}
int main(){
int t;
int n;
int q;
int l,r;
scanf("%d",&t);
while(t--){
scanf("%d",&n);
for(int i=1;i<=n;i++){
scanf("%d",&num[i]);
}
gr[n][0]=1;
gr[n][1]=n;
gcdnum[n][1]=num[n];
for(int i=n-1;i>=1;i--){
gr[i][0]=1;
gr[i][1]=i;
gcdnum[i][1]=num[i];
for(int j=1;j<=gr[i+1][0];j++){
int temploca=gr[i][0];
int temp=gcd(num[i],gcdnum[i+1][j]);
if(temp==gcdnum[i][temploca]){
gr[i][temploca]=gr[i+1][j];
}
else{
gr[i][0]++;
temploca++;
gr[i][temploca]=gr[i+1][j];
gcdnum[i][temploca]=temp;
}
}
}
//printf("wo shi da hao ren");
/*for(int i=1;i<=n;i++){
for(int j=1;j<=gr[i][0];j++){
printf("%d %lld %lldha\n",i,gr[i][j],gcdnum[i][j]);
}
}*/
scanf("%d",&q);
while(q--){
scanf("%d%d",&l,&r);
long long int ans=0;//计算过程中要强制转化为long long int
for(int i=l;i<=r;i++){
if(gr[i][1]<=r){
ans+=((long long int)gr[i][1]-i+1)*gcdnum[i][1];
}
else{
ans+=((long long int)r-i+1)*gcdnum[i][1];
}
for(int j=2;j<=gr[i][0];j++){
if(gr[i][j]<=r){
ans+=((long long int)gr[i][j]-gr[i][j-1])*gcdnum[i][j];
}
else{
ans+=((long long int)r-gr[i][j-1])*gcdnum[i][j];
break;
}
}
}
printf("%lld\n",ans);
}
}
}