### The 12th Zhejiang University Programming Contest

The 12th Zhejiang University Programming Contest 第十二屆浙大校賽題，在zoj上是：3591-3599

zoj 3591 Nim 這個就是nim的變形，列出給定的a數組，b[i]為前i個數的異或值，則看b[i]中不相同兩個數構成的對的個數就是了，當然還要加上單個不為零的情況。

```#include <iostream>
#include <stdio.h>
#include <string.h>
#include <algorithm>
using namespace std;

int a[100010], b[100010];

void deal(int N ,int S,int W)
{
int g = S;
for (int i=0; i<N; i++) {
a[i] = g;
if( a[i] == 0 ) { a[i] = g = W; }
if( g%2 == 0 ) { g = (g>>1); }
else           { g = (g>>1) ^ W; }

if(i != 0) a[i] = a[i]^a[i-1];
}
}

int main()
{
int t;
cin >> t;
int n,s,w;
while(t--)
{
cin >> n >> s >> w;
deal(n,s,w);

memset(b,0,sizeof(0));
sort(a,a+n);
int kk = 1;
b[0] = 1;
for(int i = 1;i < n;i++)
{
if(a[i] != a[i-1])
{
b[kk] = 1;a[kk++] = a[i];
}
else b[kk-1]++;
}
long long re = 0;
//for(int i = 0;i < kk;i++) cout << a[i] << " " << b[i] << "\n";
for(int i = 0;i < kk;i++)
re += (long long)(n - b[i]) * b[i];

re = re/2;
re += n;
if(a[0] == 0) re -= b[0];

cout << re << "\n";
}
return 0;
}
```

zoj 3592 Flipping the Board 整套題中最難得一個，不會！

zoj 3593 One Person Game 數學題

```#include<stdio.h>
#include<stdlib.h>
#include<algorithm>
#include<iostream>
using namespace std;
typedef long long ll;
ll gcd(ll a,ll b)
{
if(b==0)return a;
else return gcd(b,a%b);
}
ll ext_gcd(ll a,ll b,ll& x,ll& y)
{
ll t,ret;
if (!b)
{
x=1,y=0;
return a;
}
ret=ext_gcd(b,a%b,x,y);
t=x,x=y,y=t-a/b*y;
return ret;
}
ll get(ll &re,ll xx,ll yy)
{
if(xx*yy>=0)re=min(re,max(abs(xx),abs(yy)));
else re=min(re,abs(xx)+abs(yy));
return re;
}

ll deal(ll &re,ll x,ll y,ll addx,ll addy)
{
get(re,x,y);
return re;
}
{
ll r = (long long)0x7fffffff*10000000,k,kx,ky;

return r;
}
int main()
{
ll A,B,a,b,t,d,x,y;
cin>>t;
while(t--)
{
cin>>A>>B>>a>>b;
A=B-A;
if(!A)printf("0\n");
else
{
d=gcd(a,b);
if(A%d) printf("-1\n");
else
{
A/=d;
a/=d;
b/=d;
ext_gcd(a,b,x,y);
x=x*A;
y=y*A;
cout<<get_step(x,y,b,a)<<endl;
}
}
}
return 0;
}
```
zoj 3594 給出公元多少年，給出甲子表示，題目挺簡單，但是有一個坑，公元紀年沒有公元0年直說，公元前1年之后是公元1年！！！！長知識了！

zoj 3595 Two Sequences  高數題，真心的跪了，大一學的東西全部忘干凈了，什么無窮級數，什么微分方程，什么求導數，而且有比較復雜的公式變換，囧，就這樣吧，結果很簡單

```#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cmath>
using namespace std;
double a0,x;
int N;
int main()
{
while(scanf("%lf",&a0)!=EOF)
{
scanf("%d",&N);
double s=0.0;
for(int i=0;i<N;i++)
{
scanf("%lf",&x);
s+=x*x/2.0+x;
}s/=(double)N;
printf("%.8f\n",a0*exp(s));
}
return 0;
}
```

zoj 3596 Digit Number 這個題也是比較難得，但是看解題報告這個是廣搜，記憶化的廣搜，奇了！！看懂了思路，但是思路還是很模糊，這個都能想出來，看來我的水平還得繼續提升啊！！

zoj 3597 Hit the Target! 線段樹！！！

```#include <iostream>
#include <stdio.h>
#include <string.h>
#include <algorithm>
using namespace std;
#define N 50010
//Ïß¶ÎÊ÷/////////////////////////
int lazy[N*4],num[N*4];
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1

void PushUp(int rt)
{
num[rt] = max(num[rt<<1],num[rt<<1|1]);
}
void PushDown(int rt,int m)
{
if(lazy[rt])
{
lazy[rt<<1] += lazy[rt];
lazy[rt<<1|1] += lazy[rt];

num[rt<<1] += lazy[rt];
num[rt<<1|1] += lazy[rt];
lazy[rt] = 0;
}
}
void init(int n)
{
for(int i = 0;i <= n*4+1;i++)
{
lazy[i] = 0;
num[i] = 0;
}
}
void update(int L,int R,int c,int l,int r,int rt)
{
if(R - L < 0) return;
if(L <= l && r <= R)
{
lazy[rt] += c;
num[rt] += c;
return;
}
PushDown(rt,r-l+1);
int m = (l+r)>>1;
if(L <= m) update(L,R,c,lson);
if(m < R) update(L,R,c,rson);
PushUp(rt);
}
//////////////////////////////////

int shot[N];

#define M 100010
struct note
{
int a,b;
}data[M];
bool cmp(const note a,const note b)
{
return a.a < b.a || (a.a == b.a && a.b < b.b);
}
int n,m,p,q,k;
void deal(int i,int c)
{
if(shot[i])
{
int t = shot[i];
int pre = data[t].b-1;
do
{
update(max(pre+1,data[t].b),min(m,data[t].b+q-1),c,1,m,1);
pre = data[t].b+q-1;
t++;
}while(t <= k && data[t].a == data[t-1].a);
}
}
int main()
{
int t;
cin >> t;
while(t--)
{
scanf("%d%d%d%d",&n,&m,&p,&q);
scanf("%d",&k);
memset(shot,0,sizeof(shot));

for(int i = 1;i <= k;i++) scanf("%d%d",&data[i].a,&data[i].b);

if(k == 0) {cout << "0.00\n";continue;}

sort(data+1,data+k+1,cmp);

shot[data[1].a] = 1;
for(int i = 2;i <= k;i++)
if(data[i].a != data[i-1].a) shot[data[i].a] = i;

init(m);//
for(int i = 1;i <= p;i++) deal(i,1);

int now = p;
double re = 0;
while(1)
{
re += num[1];
now++;if(now > n) break;
deal(now,1);
deal(now-p,-1);
}
printf("%.2f\n",re / (n-p+1));
}
return 0;
}
```
zoj 3598 Spherical Triangle 計算幾何，跳過，自己不會！

zoj 3599 Game 博弈，這一套題中居然有兩個博弈！！！真心不知道出題者怎么想的。

```/*
zju比賽時被gao了，半天找不到好的規律，特在次幾下這一類的博弈問題通解。

H(1) = 1，H(k+1) = H(k) + H(m)，m = min{ j | f( H(j) ) >= H(k)}。

*/
#include <iostream>
using namespace std;

long long data[1000000];

long long deal(int m,int n)
{
data[1] = 1;
int pre = 1;
for(int k = 2;;k++)
{
int j;
for(j = pre;j < k;j++) if(data[j]*m >= data[k-1]) break;
pre = j;
data[k] = data[k-1]+data[j];
cout << data[k] << " " ;
//cout << n << " " << k << " \n " ;
if(data[k] > n) return n-k+1;
}
return 0;
}
int main()
{
int t;
cin >> t;
while(t--)
{
int m,n;
cin >> m >> n;
cout << deal(m,n) << "\n";
}
return 0;
}
```