A very hard Aoshu problem
这个题敲一个dfs就可以AC了,注意等号左边dfs的时候hash一下,右边取hash的值加起来。然后枚举等号的位置就好了。
#include <cstdio>
#include <string.h>
#include <map>
using namespace std;
typedef long long ll;
map <ll,int> hash;
ll tot;
char s[100];
int dfs(int l, int r, ll pre, ll sum, int mode)
{
if (l>r)
{
if (pre==0){
if (mode==0){
hash[sum]++;
//printf("sum=%d\n",sum);
}
else{
tot+=hash[sum];
}
}
return sum;
}
dfs(l+1,r,0,sum+pre*10+s[l]-'0',mode);
dfs(l+1,r,pre*10+s[l]-'0',sum,mode);
return sum;
}
int main()
{
int i,j,k;
while ( scanf("%s",s), *s!='E' )
{
tot=0;
for (i=0; i<strlen(s)-1; i++){
hash.clear();
dfs(0,i,0,0,0);
dfs(i+1,strlen(s)-1,0,0,1);
}
printf("%I64d\n",tot);
}
return 0;
}
Aeroplane chess
期望DP,要记住每个点到达的概率,步数等状态,直接飞走的点另外考虑。
另外,正着推和反着推不太一样,可以先在纸上模拟一下,感觉过样例一般都能AC
#include <stdio.h>
#include <string.h>
#define NN 102100
const double p=1.0/6.0;
double dp[NN][2];
int n,m,x,y;
int to[NN],from[NN];
int flight(int k){
if (to[k]==-1) return k;
int tmp=flight(to[k]);
to[k]=tmp;
return tmp;
}
void Readln(){
memset(dp,0,sizeof(dp));
memset(to,-1,sizeof(to));
memset(from,-1,sizeof(from));
for (int i=0; i<m; i++)
{
scanf("%d %d",&x,&y);
to[x]=y;
from[y]=x;
}
for (int i=0; i<=n; i++)
flight(i);
}
int main(){
int i,j,k;
while ( scanf("%d %d",&n,&m),!(m==0 && n==0) )
{
Readln();
dp[0][0]=0;
dp[0][1]=1;
for (i=0; i<n; i++ )
{
if (to[i]!=-1) continue;
if (dp[i][1]<1e-8) continue;
dp[i][0]=dp[i][0]/dp[i][1];
// dp[i][1]=1;
for (j=1; j<=6 ; j++)
{
int k;
k=flight(i+j);
dp[k][0]+=( (dp[i][0]+1) /6.0 * dp[i][1]);
dp[k][1]+=dp[i][1]*p;
}
// printf("grid=%d exp=%.4f gailv=%.4f\n",i,dp[i][0],dp[i][1]);
}
double sum=0;
double sp=0;
for (i=n;i<n+6;i++) {
// sum+=dp[i][0];
sum+=dp[i][0];
sp +=dp[i][1];
// printf("%.4f\n",dp[i][0]);
}
printf("%.4f\n",sum/sp);
/* for (i=0; i<=n; i++){
printf("%d to %d\n",i,to[i]);
printf("%d from %d\n",from[i],i);
}*/
}
return 0;
}
Sum
这题用容斥来做,p分解质因数,得到q[],凡是q[]的倍数都不与p互质,用容斥算算吧
c那个操作不多,可以把c通通记下来,询问的时候再修正。
#pragma comment(linker, "/STACK:1024000000,1024000000")
#include <stdio.h>
#include <map>
#include <cmath>
using namespace std;
#define NN 651000
typedef __int64 LL;
map < LL , LL > op;
map < LL , LL >::iterator it;
LL n,m;
LL gcd(LL a,LL b){ return b?gcd(b,a%b):a;}
LL sum[NN];
/*
LL getsum(LL x, LL y, LL p){
LL ret=0;
for (LL i=x; i<=y; i++)
{
if ( gcd(i,p)==1 ) ret+=i;
}
return ret;
}
*/
LL dfs(LL k, LL deep, LL *p, LL n, LL y, LL mul)
{
if (deep==0)
{
LL count=y/mul;
// printf("mul=%lld\n",count*(count+1)*mul/2);
return (count*(count+1)*mul/LL(2));
}
LL sum=0;
for (LL i=k; i<n; i++)
{
mul*=p[i];
sum+=dfs(i+1,deep-1,p,n,y,mul);
mul/=p[i];
}
return sum;
}
LL gets(LL n,LL *p)//[1,n] p
{
if (n==1) return 1;
if (n<1) return 0;
LL ret=0,sg=1;
for (LL i=1;i<=p[0];i++)
{
ret+=sg*dfs(0,i,p+1,p[0],n,1);
sg=sg*(-1);
// printf("i=%d ret=%lld\n",i,ret);
}
return (sum[n]-ret);
}
LL getsum(LL x, LL y, LL px)
{
LL count=0,i=2;
LL p[50];
LL sp=sqrt(px+0.0);
while (px>1)
{
if (px%i == 0)
{
while (px%i == 0) px/=i;
p[++count]=i;
}
i++;
if (i>sp) i=px;
}
p[0]=count;
LL ret;
ret=gets(y,p)-gets(x-1,p);
// for (LL i=1; i<=count; i++) printf("p[%d] = %d\n",i,p[i]);
return ret;
}
LL Query(LL x, LL y, LL p){
LL ret=0;
LL tmp=getsum(x,y,p);
ret=tmp;
// if (p==1) ret = (sum[y]-sum[x-1]);
for (it=op.begin();it!=op.end();it++)
{
LL x1,c1;
x1=it->first;
c1=it->second;
if (x1>=x&&x1<=y)
{
if ( gcd(x1,p)==1 ) ret-=x1;
if ( gcd(c1,p)==1 ) ret+=c1;
}
}
return ret;
}
void init(){
sum[0] = 0;
for(LL i = 1; i < NN; i++)
sum[i] = sum[i-1] + i;
}
void fun(){
LL i,j,k;
op.clear();
LL ch,x,y,p;
scanf("%I64d %I64d",&n,&m);
for (i=0; i<m; i++)
{
scanf("%I64d",&ch);
if (ch==1)
{
scanf("%I64d %I64d %I64d",&x,&y,&p);
printf("%I64d\n" ,Query(x,y,p) );
}
else
{
scanf("%I64d %I64d",&x,&y);
op[x]=y;
}
}
}
int main(){
init();
LL T;
/* LL p[30];
p[0]=2;p[1]=3;p[2]=2;
printf("%I64d\n",getsum(1,3,6));
return 0;*/
scanf("%I64d",&T);
while (T--)
{
fun();
}
return 0;
}