今天中午补了补昨天的题。
有异或题。理解下,异或的性质,下午也做了一道异或的题,就是根据公式简化公式,最后达到降低复杂度的目的。
有拿到单调队列的题。
代码:
#include <cstdio>
#include <iostream>
#include <cstring>
using namespace std;
#define ll long long
const int maxn = 1e7+10;
const int INF = 0x3f3f3f3f;
int a[maxn];
int Q[maxn];
int t,h,i;
ll A,B;
int n,m,k,p,q,r,mod;
int T;
int main()
{
scanf("%d", &T);
while (T--)
{
scanf("%d%d%d%d%d%d%d",&n,&m,&k,&p,&q,&r,&mod);
for(i=1;i<=k;i++)
{
scanf("%d",&a[i]);
}
for(i=k+1;i<=n;i++)a[i]=(1LL*p*a[i-1]+1LL*q*i+r)%mod;
A=B=t=0;
h=1;
for(i=n;i;i--)
{
while(h<=t&&a[Q[t]]<=a[i])t--;
Q[++t]=i;
if(i+m-1<=n)
{
while(Q[h]>=i+m)h++;
A+=i^a[Q[h]];
B+=i^(t-h+1);
}
}
printf("%lld %lld\n",A,B);
}
return 0;
}
还有状压dp的题,看来需要 遇事不决就打表,数据太小就状压。
状压dp,背包思想,再滚动一下。
代码:
# include <bits/stdc++.h>
using namespace std;
typedef long long LL;
const int mod = 1e9+7;
int dp[2][1025], num[1025], sta[1025], ans[6];
void add(int &x, int y)
{
x += y;
if(x >= mod) x -= mod;
}
void sub(int &x, int y)
{
x -= y;
if(x < 0) x += mod;
}
int main()
{
char c;
int n, q, T, u, v, cnt=0;
for(int i=0; i<1024; ++i)
{
num[i]= num[i>>1]+(i&1);//i的二进制有几个1
if(~num[i]&1) sta[cnt++] = i;//sta保存偶数个1的二进制数
}
for(scanf("%d",&T);T;--T)
{
memset(dp, 0, sizeof(dp));
scanf("%d%d",&n,&q);
int now = 0;
dp[0][0] = 1;
while(q--)
{
getchar();
c = getchar();
scanf("%d%d",&u,&v);
--u,--v;
memset(ans, 0, sizeof(ans));
int tmp = (1<<u) | (1<<v);
if(c == '+')
{
for(int i=0; i<cnt&&sta[i]<(1<<n); ++i)
{
int cur = sta[i];
dp[now^1][cur] = dp[now][cur];
if((cur&tmp) == tmp) add(dp[now^1][cur],dp[now][cur^tmp]);
add(ans[num[cur]/2],dp[now^1][cur]);
}
}
else
{
for(int i=0; i<cnt&&sta[i]<(1<<n); ++i)
{
int cur = sta[i];
dp[now^1][cur] = dp[now][cur];
if((cur&tmp) == tmp) sub(dp[now^1][cur],dp[now][cur^tmp]);
add(ans[num[cur]/2],dp[now^1][cur]);
}
}
now ^= 1;
for(int i=1; i<=n/2; ++i) printf("%d%c",ans[i],i==n/2?'\n':' ');
}
}
return 0;
}
下午做了老师发的题。就是一道异或的题,多了解下,异或性质,一道set题,一道欧拉路径的题。
晚上为了试一下,学习的splay,试了试,基础题,咳咳,代码不好写。晚上继续去cf放松放松吧。