bzoj突然有了snoi的题,就把以前做过的拷过去好了,所以重新做一下写一个题解好了。
DAY1 T1
求一个数列: A1=1,An=Sn+nk n≤1018,k≤10
关于之前的sum的式子都可以化为一个前缀和式 f[i]=2∗f[i−1]+nk
于是我们构造一个k+2唯矩阵表示答案和 i 的 0−k 次幂。
然后我们用二项式定理来推算 (n+1)k=∑kr=0Crknk−r
时间复杂度: O(k3∗logn)
code:还是复制的
#include
using namespace std;
#define rep(i,l,r) for(int i=l;i<=r;++i)
#define rpe(i,r,l) for(int i=r;i>=l;--i)
#define dyes cerr<<"yes"<
#define rpp(i,x,e,head) for(int i=head[x];~i;i=e[i].next)
template <class Type> inline void read(Type &cur){
Type ret=0,flag=1;
char ch=getchar();
while(ch<'0'||ch>'9'){
if(ch=='-')
flag=-1;
ch=getchar();
}
while(ch>='0'&&ch<='9'){
ret=ret*10+ch-'0';
ch=getchar();
}
cur=ret*flag;
}
const int mod=1e9+7;
typedef long long ll;
ll n,k;
struct matrix{
ll s[20][20];
matrix(){memset(s,0,sizeof(s));}
}A,I;
matrix operator * (const matrix &a,const matrix &b){
matrix c;
rep(i,0,14){
rep(j,0,14){
rep(k,0,14){
c.s[i][j]=(c.s[i][j]+a.s[i][k]*b.s[k][j]%mod+mod)%mod;
}
}
}
return c;
}
matrix qpow(matrix a,ll x){
matrix c=I;
while(x){
if(x&1)
c=c*a;
a=a*a;
x>>=1;
}
return c;
}
int main(int argc,const char * argv[]){
read(n);read(k);
A.s[0][0]=1;
rep(i,1,k){
A.s[i][0]=A.s[i][i]=1;
rep(j,0,i){
A.s[i][j]=(A.s[i-1][j]+A.s[i-1][j-1])%mod;
}
}
rep(i,0,14)
I.s[i][i]=1;
A.s[k+1][k]=1;A.s[k+1][k+1]=2;
matrix ans;
ans=qpow(A,n-1);
ll fans=0;
rep(i,0,k){
fans=((fans+ans.s[k+1][i]+ans.s[k][i])%mod+mod)%mod;
}
cout<return 0;
}
T2
离线询问: ∑∞x=0get(l1,r1,x)∗get(l2,r2,x)
get表示区间 [l,r] 中x的出现次数。
q,n≤105
我们把这个式子拆开,
维护: (l1,r2)[x],(l1,l2−1)[l],(r1+1,r2)[r],(r1+1,l2−1)[c]
分别代表区间内数字的个数。
那么 ans=(x2−l2−r2+c2)2
于是开始愉快的莫队吧!
拷贝代码:
//维护:(l1,r2)[z],(l1,l2-1)[l],(r1+1,r2)[r],(r1+1,l2-1)[c]
//ans=(x^2-l^2-r^2)/2+(c^2)/2;
#include
using namespace std;
#define rep(i,l,r) for(int i=l;i<=r;++i)
#define rpe(i,r,l) for(int i=r;i>=l;--i)
#define dyes cerr<<"yes"<
#define rpp(i,x,e,head) for(int i=head[x];~i;i=e[i].next)
template <class Type> inline void read(Type &cur){
Type ret=0,flag=1;
char ch=getchar();
while(ch<'0'||ch>'9'){
if(ch=='-')
flag=-1;
ch=getchar();
}
while(ch>='0'&&ch<='9'){
ret=ret*10+ch-'0';
ch=getchar();
}
cur=ret*flag;
}
typedef long long ll;
const int maxn=5e4+10;
inline ll read(){
ll ret=0,flag=1;char ch=getchar();
while(ch<'0'||ch>'9'){
if(ch=='-')
flag=-1;
ch=getchar();
}
while(ch>='0'&&ch<='9'){
ret=(ret<<1)+(ret<<3)+ch-'0';
ch=getchar();
}
return ret*flag;
}
ll belong[maxn];
struct node{
int l,r;
int id;int mul;
}e[maxn<<2];
inline bool cmp(const node &a,const node &b){
if(belong[a.l]==belong[b.l])
return a.rreturn belong[a.l]int cnt=0;
inline void add(ll l,ll r,ll mul,ll id){
e[++cnt].l=l;e[cnt].r=r;
e[cnt].id=id;e[cnt].mul=mul;
}
int n,m;
ll a[maxn];int num[maxn];
inline ll squre(ll x){return x*x;}
ll ans;
inline void upd(ll p,ll delta){
ans-=squre(num[a[p]]);
num[a[p]]+=delta;
ans+=squre(num[a[p]]);
}
ll tans[maxn];
inline void modui(){
ans=0;
for(int i=1,l=1,r=0;i<=cnt;++i){
for(;l1);
for(;l>e[i].l;--l)
upd(l-1,1);
for(;r1,1);
for(;r>e[i].r;--r)
upd(r,-1);
tans[e[i].id]+=ans*(e[i].mul);
}
}
int main(int argc,const char * argv[]){
read(n);
rep(i,1,n)
read(a[i]);
read(m);
int size=sqrt(n);
rep(i,1,n)
belong[i]=(i-1)/size+1;
int l1,l2,r1,r2;
rep(i,1,m){
read(l1);read(r1);read(l2);read(r2);
add(l1,r2,1,i);
add(l1,l2-1,-1,i);
add(r1+1,r2,-1,i);
add(r1+1,l2-1,1,i);
}
sort(e+1,e+cnt+1,cmp);
modui();
for(int i=1;i<=m;i++)
cout<2LL<return 0;
}