ZOJ 3279 ants http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3279
树状数组,你不学就永远不会;
巧妙之处在于 q 处的查找上,采用二分方式+计算前缀和;
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
#define mem(a) memset(a, 0, sizeof(a));
const int maxn = 100010;
int c[maxn];
int a[maxn];
int n;
int lowbit(int x)
{
return x&(-x);
}
int sum(int x)
{
int cnt=0;
while(x>0)
{
cnt+=c[x];
x-=lowbit(x);
}
return cnt;
}
void add(int x,int d)
{
while(x<=n)
{
c[x]+=d;
x+=lowbit(x);
}
}
int main()
{
while(scanf("%d",&n)!=EOF)
{
mem(c);mem(a);
for(int i=1;i<=n;i++)
{
scanf("%d",&a[i]);
add(i,a[i]);
}
int k;char ch;
scanf("%d",&k);
for(int i=1;i<=k;i++)
{
getchar();
scanf("%c",&ch);
if(ch=='p')
{
int id,num;
scanf("%d%d",&id,&num);
add(id,num-a[id]);
a[id]=num;
}
else if(ch == 'q')
{
int r;
scanf("%d",&r);
int left_=0;int right_=n;
while(left_<right_)
{
int m=left_+(right_-left_)/2;
if(sum(m)>=r) right_=m;
else left_=m+1;
}
printf("%d\n",left_);
}
}
}
return 0;
}
HDU 1005
http://acm.hdu.edu.cn/showproblem.php?pid=1005 明显的
数学
需要先找出其循环,然后就是需要条理一点的细节处理;
判断循环的方式可以很好:可以将其相邻两数字化成十进制数存一下vis,而后判断即可;
#include<cstdio>
#include<cstring>
const int maxn = 100;
int a,b,n;
int f[maxn];
int main()
{
while(scanf("%d%d%d",&a,&b,&n)!=EOF)
{
if(a==0&&b==0&&n==0)
break;
memset(f,0,sizeof(f));
f[1]=1;
f[2]=1;
int period;
int start;
int ok=0;
for(int i=3;i<=55;i++)
{
f[i]=(a * f[i-1] + b * f[i-2])%7;
for(int j=2;j<=i-1;j++)
{
if(f[i-1]==f[j-1]&&f[i]==f[j])
{
start=j;
period=i-j;
ok=1;
break;
}
}
if(ok) break;
}
f[0]=f[start+period];
int ans;
if(n>start)
{
ans=(n-start)%period;
printf("%d\n",f[start+ans]);
}
else
{
ans=n;
printf("%d\n",f[ans]);
}
}
return 0;
}
还有一道简单模拟,不写;
还有其他一道前面总结过了,就是这样。