您的位置:首页 > 其它

CQOI2016 day2 模拟赛总结

2016-04-14 16:26 357 查看
T1

N=pq

r=(p-1)(q-1)

ed=1(mod r)

c^d=n(mod N)

第一步rho,第二步直接算

第三步exgcd,第四步快速幂

强行算就可以了

exgcd忘开longlong 100->30

T2

蜜汁题意

读懂过后发现建字典树

然后随便维护个单调栈搞搞就OK了

时间nlogn

T3

每次考虑把最大的出堆,把次大的入堆

hash去重

这样是31*k*log的

很慢对不对,我们考虑把31搞到可持久化线段树里面

这样每次修改就只用修改一条链了= =

可是要hash去重。。。开个hashmap就好

然后常数卡不下来了QAQ bzoj只给10s不让人活啦

所以还是要好好学其他人的神奇方法。。。

day2 30+100+60

第一个30纯属脑抽

//Copyright(c)2016 liuchenrui
#include<bits/stdc++.h>
#define LL long long
using namespace std;
LL e,N,c,p,q,n,d,r;
LL ksc(LL a,LL b,LL c){
LL ans=0;
while(b){
if(b&1LL){
ans=ans+a;
if(ans>=c)ans-=c;
}
b>>=1LL;
a=a+a;if(a>=c)a-=c;
}
return ans;
}
LL ksm(LL a,LL b,LL c){
LL ans=1;
while(b){
if(b&1LL){
ans=ksc(ans,a,c);
}
b>>=1LL;
a=ksc(a,a,c);
}
return ans;
}
LL exgcd(LL a,LL b,LL &x,LL &y){
if(b==0){
x=1;y=0;return a;
}
LL z=exgcd(b,a%b,x,y);
LL t=x;x=y;y=t-a/b*y;
return z;
}
int windows_rand(){
return rand()&32767;
}
LL gcd(LL a,LL b){
return b==0?a:gcd(b,a%b);
}
LL prho(LL c,LL n){
LL i,x,y,k,d;
i=1;
x=y=windows_rand()%n;
k=2;
do{
i++;
d=gcd(n+y-x,n);
if(d>1&&d<n)return d;
if(i==k)y=x,k<<=1LL;
x=(ksc(x,x,n)+n-c)%n;
}while(y!=x);
return n;
}
void rho(LL n){
LL t=n;
while(t>=n){
t=prho(windows_rand()%(n-1)+1,n);
}
p=t;q=N/t;return;
}
int main(){
freopen("crack.in", "r",stdin);
freopen("crack.out","w",stdout);
cin>>e>>N>>c;
rho(N);
r=(p-1)*(q-1);
LL p;
exgcd(e,r,d,p);
d=((d%r)+r)%r;
cout<<d<<" "<<ksm(c,d,N)<<endl;
}


#include<bits/stdc++.h>
using namespace std;
void splay(int &v){
char s=getchar();v=0;
while(s>'9'||s<'0')s=getchar();
while(s>='0'&&s<='9')v=v*10+s-'0',s=getchar();
}
int son[32000000][2],t[32000000],tot,cnt;

int main(){
freopen("route.in","r",stdin);
freopen("route.out","w",stdout);

int q;splay(q);
for(;q--;){
static char op[4];
static int s[35],dl[35];
scanf("%s",op+1);
if(op[1]=='Q'){
int a,b,c,d,l,r;
splay(a),splay(b),splay(c),splay(d),splay(l),splay(r);
for(int i=8 ;i>=1 ;i--)s[i]=a&1,a>>=1;
for(int i=16;i>=9 ;i--)s[i]=b&1,b>>=1;
for(int i=24;i>=17;i--)s[i]=c&1,c>>=1;
for(int i=32;i>=25;i--)s[i]=d&1,d>>=1;
int now=0,ans=0,top=0;
for(int i=1;i<=32;i++){
now=son[now][s[i]];
if(t[now]){
while(top&&t[now]<dl[top])top--;
dl[++top]=t[now];
}
if(now==0)break;
}
for(int i=1;i<=top;i++){
if(l<=dl[i] && dl[i]<=r)ans++;
}
printf("%d\n",ans);
}
else{
cnt++;
int a,b,c,d,p;
splay(a),splay(b),splay(c),splay(d),splay(p);
for(int i=8 ;i>=1 ;i--)s[i]=a&1,a>>=1;
for(int i=16;i>=9 ;i--)s[i]=b&1,b>>=1;
for(int i=24;i>=17;i--)s[i]=c&1,c>>=1;
for(int i=32;i>=25;i--)s[i]=d&1,d>>=1;
int now=0;
for(int i=1;i<=p;i++){
if(!son[now][s[i]])son[now][s[i]]=++tot;
now=son[now][s[i]];
}
t[now]=cnt;
}
}
}


//liuchenrui
#include<bits/stdc++.h>
#include<hash_map>
#define LL long long
#define H 1000001007ULL
#define ULL unsigned long long
#define ld long double
using namespace std;
LL n;int k;
bool ispri[140];
int pri[140],tot;
ULL h[35];
int root[2000000],ls[20000000],rs[20000000],cnt;
LL ji[20000010];ULL hash[20000000];
int num[55];
struct node{
int id;
friend bool operator < (const node &a,const node &b){
return ji[root[a.id]]<ji[root[b.id]];
}
};
namespace __gnu_cxx{
template<> struct hash<ULL>{
size_t operator()(ULL x) const{
return x;
}
};
}
__gnu_cxx::hash_map<ULL,bool>s;
void build(int &now,int l,int r,int pos,int v,LL f){
now=++cnt;
if(l==r){
if(l==pos)hash[now]=v,ji[now]=f;
else ji[now]=1;
return;
}
int mid=l+r>>1;
build(ls[now],l,mid,pos,v,f),build(rs[now],mid+1,r,pos,v,f);
hash[now]=hash[ls[now]]*(h[r-mid])+hash[rs[now]];
ji[now]=ji[ls[now]]*ji[rs[now]];
}
void getval(int now,int l,int r){
if(l==r){
num[l]=hash[now];
return;
}
int mid=l+r>>1;
getval(ls[now],l,mid);
getval(rs[now],mid+1,r);
}
void insert(int pre,int &now,int l,int r,int pos,int v){
if(!now)now=++cnt;
if(l==r){
hash[now]=v;
LL t=1;
for(int i=1;i<=v;i++){
t*=(LL)pri[pos];
}
ji[now]=t;
return;
}
int mid=l+r>>1;
if(pos<=mid){
if(ls[pre]==ls[now])ls[now]=0;
insert(ls[pre],ls[now],l,mid,pos,v);
if(!rs[now])rs[now]=rs[pre];
}
else{
if(rs[pre]==rs[now])rs[now]=0;
insert(rs[pre],rs[now],mid+1,r,pos,v);
if(!ls[now])ls[now]=ls[pre];
}
hash[now]=hash[ls[now]]*(h[r-mid])+hash[rs[now]];
ji[now]=ji[ls[now]]*ji[rs[now]];
}
ULL gethash(ULL prehash,int pos){
prehash-=h[31-pos];
if(pos!=1)prehash+=h[32-pos];
return prehash;
}
int main(){
freopen("smooth.in","r",stdin);
freopen("smooth.out","w",stdout);
cin>>n>>k;
for(int i=2;i<=128;i++){
if(!ispri[i]){
for(int j=i+i;j<=128;j+=i){
ispri[j]=1;
}
pri[++tot]=i;
}
}
h[0]=1;
for(int i=1;i<=32;i++){
h[i]=h[i-1]*H;
}
priority_queue<node>que;
for(int i=1;i<=31;i++){
ld x=1;int lim;
for(int j=1;;j++){
x*=(ld)pri[i];
if(x>n){
lim=j-1;break;
}
}
LL y=1;
for(int j=1;j<=lim;j++){
y*=(LL)pri[i];
}
build(root[i],1,31,i,lim,y);
que.push((node){i});
s[hash[root[i]]]=1;
}
int rcnt=31;
for(int T=1;T<k;T++){
int f=que.top().id;que.pop();
ULL nh=hash[root[f]];
getval(root[f],1,31);
for(int i=1;i<=31;i++){
if(num[i]&&!s[gethash(nh,i)]){
s[gethash(nh,i)]=1;
++rcnt;
insert(root[f],root[rcnt],1,31,i,num[i]-1);
if(i!=1)insert(root[f],root[rcnt],1,31,i-1,num[i-1]+1);
que.push((node){rcnt});
}
}
}
printf("%lld\n",ji[root[que.top().id]]);
cerr<<clock()<<endl<<rcnt<<endl;
}


最后那个会T,所以你懂得
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: