【bzoj4035】[HAOI2015]陣列遊戲
阿新 • • 發佈:2018-11-19
題目連結
函式niubia
設
為第
位為白色的估價函式
顯然有
然後有個顯(hen)然(nan)發現的性質
當
時,有
為什麼有這個結論呢,讓我們來嘗試證明一下
首先當
時,顯然成立,因為
都等於
當 時, 與 相同意味著他們的 函式轉移形式也相同,那麼通過簡單數學歸納法就能發現轉移給他們的 值也相同,所以他們的 也相同(我也不知道我在說什麼)
反正大概就是這樣了。。。。
然後xjb分塊一下就好了,複雜度是 的,但是常數小,所以完全過得去
程式碼:
#include<cstdio>
#include<vector>
#include<queue>
#include<ctime>
#include<algorithm>
#include<cstdlib>
#include<stack>
#include<cstring>
#include<cmath>
using namespace std;
typedef long long LL;
const int INF = 2147483647;
const int maxn = 100010;
const int crz = 100007;
struct data{
int id,val;
};
vector<data> ha[maxn];
int n,m,b,ans,tot;
int sg[maxn],L[maxn],R[maxn],vis[maxn];
int stk[maxn],top;
inline LL getint()
{
LL ret = 0,f = 1;
char c = getchar();
while (c < '0' || c > '9')
{
if (c == '-') f = -1;
c = getchar();
}
while (c >= '0' && c <= '9') ret = ret * 10 + c - '0',c = getchar();
return ret * f;
}
inline int find(int x)
{
int pos = x % crz;
for (int i = 0; i < ha[pos].size(); i++)
if (ha[pos][i].id == x)
return ha[pos][i].val;
}
inline void insert(int id,int val)
{
int pos = id % crz;
ha[pos].push_back((data){id,val});
}
inline void init()
{
for (int i = 1; i <= n; i = n / (n / i) + 1)
L[++tot] = i , R[tot] = n / (n / i);
for (int i = tot; i >= 1; i--)
{
vis[0] = i;
int l = L[i],r = R[i],sum = 0;
for (int j = 2 * l; j <= n; j = (n / (n / j) / l + 1) * l)
{
int cnt = n / (n / j) / l - (j - 1) / l;
vis[sum ^ find(n / j)] = i;
if (cnt & 1) sum ^= find(n / j);
}
for (int j = 0; j <= n; j++)
if (vis[j] != i) {sg[i] = j; break;}
insert(n / l,sg[i]);
}
}
int main()
{
#ifdef AMC
freopen("AMC1.txt","r",stdin);
#endif
n = getint();
init();
n = getint();
for (int i = 1; i <= n; i++)
{
ans = 0;
m = getint();
for (int j = 1; j <= m; j++)
{
int pos = getint();
int id = upper_bound(L + 1,L + tot + 1,pos) - L - 1;
ans ^= sg[id];
}
printf(ans ? "Yes\n" : "No\n");
}
return 0;
}
這種題考場上看到就直接打表好了。。