# 12.26模拟赛

T1：

（我用的分治。复杂度差一些）

T2：

绿色的点是这一次的碰撞点。

#include<bits/stdc++.h>
#define reg register int
#define il inline
#define numb (ch^'0')
using namespace std;
typedef long long ll;
il void rd(int &x){
char ch;x=0;bool fl=false;
while(!isdigit(ch=getchar()))(ch=='-')&&(fl=true);
for(x=numb;isdigit(ch=getchar());x=x*10+numb);
(fl==true)&&(x=-x);
}
namespace Miracle{
const int N=100000+5;
const int eps=0.0000001;
struct po{
double x,y;
bool friend operator <(po a,po b){
if(fabs(a.x-b.x)<eps) return a.y>=b.y;
return a.x<b.x;
}
}sta[N];
int top1;
struct line{
double k,b;
int id;
int die;
bool friend operator <(line a,line b){
if(fabs(a.k-b.k)<eps) return a.b>b.b;
return a.k<b.k;
}
}l[N],zhan[N];
int pos[N];
int top2;
int n,L,K;
po calc(line a,line b){//warning!!! pingxing !!
po ret;
ret.x=((double)b.b-(double)a.b)/((double)a.k-(double)b.k);
ret.y=b.k*ret.x+b.b;
return ret;
}
void sol(){
top1=0;
top2=0;
int i=1;
while(l[i].die) ++i;
zhan[++top2]=l[i];++i;
for(;i<=2*n;++i){
while(i<=2*n&&fabs(l[i].k-l[i-1].k)<eps) ++i;
while(i<=2*n&&l[i].die==1) ++i;
if(i>2*n) break;
while(top1&&calc(l[i],zhan[top2])<sta[top1]){
--top1;
--top2;
}
sta[++top1]=calc(l[i],zhan[top2]);
zhan[++top2]=l[i];
}
//cout<<" top2 "<<top2<<endl;
for(reg i=1;i<top2;++i){
//    cout<<zhan[i].id<<endl;
if(zhan[i].id<=n&&zhan[i+1].id>n){
printf("%d %d\n",zhan[i].id,zhan[i+1].id-n);
l[pos[zhan[i].id]].die=1;
l[pos[zhan[i+1].id]].die=1;
return;
}
}
return;
}
int main(){
rd(n);rd(L);rd(K);
int v,x;
for(reg i=1;i<=n;++i){
rd(x);rd(v);
l[i].id=i;
l[i].k=-(double)1/(double)v;l[i].b=-(double)x+eps;
}
for(reg i=n+1;i<=n+n;++i){
rd(x);rd(v);
l[i].id=i;
l[i].k=(double)1/(double)v;l[i].b=-((double)L/(double)v+(double)x);
}
sort(l+1,l+n*2+1);
for(reg i=1;i<=2*n;++i){
pos[l[i].id]=i;
}
//    for(reg i=1;i<=2*n;++i){
//        cout<<i<<" : "<<l[i].k<<" "<<l[i].b<<" "<<l[i].id<<endl;
//    }
for(reg i=1;i<=K;++i){
sol();
}
return 0;
}

}
signed main(){
Miracle::main();
return 0;
}

/*
Author: *Miracle*
Date: 2018/12/26 15:57:25
*/
View Code

O(NKlog1e9)

L=(T-t1)*v1+(T-t2)*v2

t1v1=Tv1-f

O(NK+Klog^2N+NlogN)

T3:

6位三进制数记录质因子用了几个。

#include<bits/stdc++.h>
#define reg register int
#define il inline
#define numb (ch^'0')
#define mp make_pair
#define fi first
#define se second
using namespace std;
typedef long long ll;
il void rd(int &x){
char ch;x=0;bool fl=false;
while(!isdigit(ch=getchar()))(ch=='-')&&(fl=true);
for(x=numb;isdigit(ch=getchar());x=x*10+numb);
(fl==true)&&(x=-x);
}
namespace Miracle{
const int N=233;
const int mod=1e9+7;
ll n;
int tot,cnt[N];
map<int,ll>dp;
map<int,ll>::iterator r;
ll pw[8]={1,3,9,27,81,243,729,2187};
ll ans;
int getnew(int st,int chos){
//    cout<<" getnew "<<st<<" "<<chos<<endl;
int ret=st;
int bit=1;
for(reg i=0;i<tot;++i){
if((chos&(1<<i))&&st/bit%3<2) ret+=bit;
bit*=3;
}
for(reg i=0;i<tot;++i){
for(reg j=i+1;j<tot;++j){
if((chos&(1<<i))&&(st/bit%2==0)&&(st/pw[j]%3!=0)) ret+=bit;
else if((chos&(1<<j)&&(st/bit%2==0)&&(st/pw[i]%3!=0))) ret+=bit;
bit<<=1;
}
}
//    cout<<" ret "<<ret<<endl;
return ret;
}
ll getsz(int chos){
ll ret=1;
//    cout<<" chos "<<chos<<endl;
for(reg i=0;i<tot;++i){
if(chos&(1<<i)) ret=(ret*cnt[i+1])%mod;
}
//    cout<<" ret "<<ret<<endl;
return ret;
}
void divi(ll x){
for(ll i=2;i*i<=x;++i){
if(x%i==0){
++tot;
while(x%i==0) ++cnt[tot],x/=i;
}
}
if(x>1) cnt[++tot]=1;
}
int main(){
scanf("%lld",&n);
divi(n);
dp.insert(mp(0,1));
r=dp.begin();
while(r!=dp.end()){
(ans+=r->se)%=mod;
//cout<<r->fi<<" "<<r->se<<endl;
int re=0;
int bit=1;
int now=r->fi;
for(reg i=0;i<tot;++i){
if(now/bit%3<2) re|=(1<<i);
bit*=3;
}
int ban[16],top=0;
for(reg i=0;i<tot;++i){
for(reg j=i+1;j<tot;++j){
++top;
if((now/bit)&1) ban[top]=(1<<i)|(1<<j);
else ban[top]=0;
bit<<=1;
}
}
//cout<<" re "<<re<<endl;
for(reg to=re;to;to=(to-1)&re){
//    cout<<"to "<<to<<endl;
bool cont=false;
for(reg i=1;i<=top&&!cont;++i){
if(ban[i]&&(ban[i]|to)==to) cont=true;
}
if(cont) continue;
//    cout<<" ok "<<to<<endl;
int go=getnew(now,to);
if(dp.find(go)==dp.end()) dp.insert(mp(go,0));
(dp[go]+=(r->se)*getsz(to))%=mod;
}
++r;
}
ans=(ans-1+mod)%mod;
printf("%lld",ans);
return 0;
}

}
signed main(){
Miracle::main();
return 0;
}

/*
Author: *Miracle*
Date: 2018/12/26 18:58:23
*/
View Code

1.T1还是想复杂了。对于题目的度还是把握不好。hash的边走边记录的思想还是不太熟练。对于一个位置多次查询的新旧对比（类似天天爱跑步？）

2.T2一直在想怎么找一个直线和其他直线的前K个交点。。。。还是没有把握好度。由于K比较小。其实O(NK)的复杂度的话，考虑O(N)找到一个，比一股脑塞进去一堆还是要简单自然的。

3.T3这种不靠谱的状态设计。。。状态数不会太多？还是状压dp比较有把握并且其他题目处理好了再说吧。。。

posted @ 2018-12-26 20:48  *Miracle*  阅读(225)  评论(0编辑  收藏  举报