Codeplus#4 (div1)

所以谁告诉我我是越来越傻了呢还是越来越傻了呢还是越来越傻了呢。。。。。。


白金元首与七彩魔法

转化一堆坐标直接算即可。

#include<bits/stdc++.h>
#define rep(i,x,y) for (int i=(x); i<=(y); i++)
#define per(i,x,y) for (int i=(x); i>=(y); i--)
#define ll long long
#define ld long double
#define inf 1000000000
#define INF 1000000000000000000ll
#define pii pair<int,int>
#define F first
#define S second
#define all(x) (x).begin(),(x).end()
#define SZ(x) ((int)(x).size())
#define sqr(x) ((x)*(x))
#define cmin(x,y) (x)=(y)<(x)?(y):(x)
#define cmax(x,y) (x)=(y)>(x)?(y):(x)
#define mset(x,y) memset((x),(y),sizeof(x))
#define mcpy(x,y) memcpy((x),(y),sizeof(y))
using namespace std;
const ld pi=acos(-1);
const ld eps=1e-8;
 header files 
ll read(){
    char ch=getchar(); ll x=0; int op=1;
    for (; !isdigit(ch); ch=getchar()) if (ch=='-') op=-1;
    for (; isdigit(ch); ch=getchar()) x=(x<<1)+(x<<3)+ch-'0';
    return x*op;
}
void write(ll a){
    if (a<0) putchar('-'),a=-a;
    if (a>=10) write(a/10); putchar(a%10+'0');
}
// fast i/o //
#ifdef mod
ll ksm(ll x,ll p){
    ll ret=1;
    for (; p; p>>=1,x=x*x%mod) if (p&1) ret=ret*x%mod;
    return ret;
}
ll get_inv(ll x){
    return ksm(x,mod-2);
}
#else
ll ksm(ll x,ll p){
    ll ret=1;
    for (; p; p>>=1,x=x*x) if (p&1) ret=ret*x;
    return ret;
}
#endif
 qpow 
#define y1 y1_
int a1,r1,a2,r2; ld x1,y1,x2,y2,ans;
ld val(ld r,ld g,ld b){
    return 0.3*r+0.59*g+0.11*b;
}
ld cal(ld a,ld r){
    int h=(int)a/60;
    ld f=a/60-h,p=1-r,q=1-f*r,t=1-(1-f)*r;
    if (!h) return val(1,t,p);
    else if (h==1) return val(q,1,p);
    else if (h==2) return val(p,1,t);
    else if (h==3) return val(p,q,1);
    else if (h==4) return val(t,p,1);
    else return val(1,p,q);
}
ld get(ld x,ld y){
    ld tmp=atan2(y,x)/pi*180;
    tmp=90-tmp; if (tmp<0) tmp+=360;
    ld r=sqrt(sqr(x)+sqr(y));
    return cal(tmp,r);
}
void solve(){
    a1=read(),r1=read(); a2=read(),r2=read();
    x1=sin(a1/180.*pi)*r1/100.; y1=cos(a1/180.*pi)*r1/100.;
    x2=sin(a2/180.*pi)*r2/100.; y2=cos(a2/180.*pi)*r2/100.;
    ans=0;
    rep (i,0,10000){//将线段分成1e4份暴力算//1e4就够了
        ld p=i/10000.;
        cmax(ans,get(x1*p+x2*(1-p),y1*p+y2*(1-p)));
    }
    printf("%.4lf\n",(double)ans);
}
#define local
int main(){
#ifdef local
    freopen("magika.in","r",stdin); freopen("magika.out","w",stdout);
#endif
    int T=read(); while (T--) solve();
    return 0;
}
// sample data:
/*
6
30 30 30 30
120 60 120 60
270 100 270 100
30 30 120 60
120 60 270 100
270 100 30 30

0.8785
0.7540
0.2600
0.9704
0.9408
0.8785

*/

// rest:
/*
转化一堆坐标直接算即可...

*/

/*
If you find any bug in my code or solution, please tell me. Thanks so much.
email: 2411280037@qq.com
*/

组合数问题 2

用堆维护,从中间向两边扩展。注意组合数比较时,,可以求对数然后比较。

#include<bits/stdc++.h>
#define rep(i,x,y) for (int i=(x); i<=(y); i++)
#define per(i,x,y) for (int i=(x); i>=(y); i--)
#define ll long long
#define ld long double
#define inf 1000000000
#define INF 1000000000000000000ll
#define pii pair<int,int>
#define F first
#define S second
#define all(x) (x).begin(),(x).end()
#define SZ(x) ((int)(x).size())
#define sqr(x) ((x)*(x))
#define cmin(x,y) (x)=(y)<(x)?(y):(x)
#define cmax(x,y) (x)=(y)>(x)?(y):(x)
#define mset(x,y) memset((x),(y),sizeof(x))
#define mcpy(x,y) memset((x),(y),sizeof(y))
using namespace std;
const ld pi=acos(-1);
const ld eps=1e-8;
 header files 
ll read(){
    char ch=getchar(); ll x=0; int op=1;
    for (; !isdigit(ch); ch=getchar()) if (ch=='-') op=-1;
    for (; isdigit(ch); ch=getchar()) x=(x<<1)+(x<<3)+ch-'0';
    return x*op;
}
void write(ll a){
    if (a<0) putchar('-'),a=-a;
    if (a>=10) write(a/10); putchar(a%10+'0');
}
// fast i/o //
#define mod 1000000007
#ifdef mod
ll ksm(ll x,ll p){
    ll ret=1;
    for (; p; p>>=1,x=x*x%mod) if (p&1) ret=ret*x%mod;
    return ret;
}
ll get_inv(ll x){
    return ksm(x,mod-2);
}
#else
ll ksm(ll x,ll p){
    ll ret=1;
    for (; p; p>>=1,x=x*x) if (p&1) ret=ret*x;
    return ret;
}
#endif
 qpow 
#define N 1000005
int n,k,fac[N],inv[N],tot,ans,nx,ny; ld Fac[N];
void upd(int &x,int y){ x+=y; if (x>=mod) x-=mod; }
void pre(){
    fac[0]=Fac[0]=1;
    rep (i,1,N-1){
        fac[i]=(ll)fac[i-1]*i%mod;
        Fac[i]=Fac[i-1]+(ld)log(i);
    }
    inv[N-1]=ksm(fac[N-1],mod-2);
    per (i,N-2,0) inv[i]=(ll)inv[i+1]*(i+1)%mod;
}
int C(int n,int m){
    return (ll)fac[n]*inv[m]%mod*inv[n-m]%mod;
}
struct data{
    int x,y; data(int a=0,int b=0){ x=a,y=b; }
    bool operator < (const data &t) const{
        return Fac[x]+Fac[t.y]+Fac[t.x-t.y]<Fac[t.x]+Fac[y]+Fac[x-y];
    }
}a[N];
#define local
int main(){
#ifdef local
    freopen("problem2.in","r",stdin); freopen("problem2.out","w",stdout);
#endif
    pre();
    n=read(); k=read();
    if (k==1){
        cout<<C(n,n/2)<<endl; exit(0);
    }
    priority_queue<data> qu;
    rep (i,0,n){
        qu.push(data(i,i/2));
    }
    while (k){
        data now=qu.top(); qu.pop();
        if (now.y<0 || now.y>now.x) continue;
        upd(ans,C(now.x,now.y)); k--;
        if (now.x/2==now.y){
            if (now.x&1){
                qu.push(data(now.x,now.x/2+1)); continue;
            }
        }
        if (now.y<now.x/2){
            qu.push(data(now.x,now.x-now.y));
        } else{
            qu.push(data(now.x,now.x-now.y-1));
        }
    }
    cout<<ans<<endl;
    return 0;
}
// sample data:
/*
2 3

4

*/

// rest:
/*

*/

/*
If you find any bug in my code or solution, please tell me. Thanks so much.
email: 2411280037@qq.com
*/

最短路

直接建边,异或的贡献可以拆开来计算,所以只要建log条边就行了。。

#include<bits/stdc++.h>
#define rep(i,x,y) for (int i=(x); i<=(y); i++)
#define per(i,x,y) for (int i=(x); i>=(y); i--)
#define ll long long
#define ld long double
#define inf 1000000000
#define INF 1000000000000000000ll
#define pii pair<int,int>
#define F first
#define S second
#define all(x) (x).begin(),(x).end()
#define SZ(x) ((int)(x).size())
#define sqr(x) ((x)*(x))
#define cmin(x,y) (x)=(y)<(x)?(y):(x)
#define cmax(x,y) (x)=(y)>(x)?(y):(x)
#define mset(x,y) memset((x),(y),sizeof(x))
#define mcpy(x,y) memset((x),(y),sizeof(y))
using namespace std;
const ld pi=acos(-1);
const ld eps=1e-8;
 header files 
ll read(){
    char ch=getchar(); ll x=0; int op=1;
    for (; !isdigit(ch); ch=getchar()) if (ch=='-') op=-1;
    for (; isdigit(ch); ch=getchar()) x=(x<<1)+(x<<3)+ch-'0';
    return x*op;
}
void write(ll a){
    if (a<0) putchar('-'),a=-a;
    if (a>=10) write(a/10); putchar(a%10+'0');
}
// fast i/o //
#ifdef mod
ll ksm(ll x,ll p){
    ll ret=1;
    for (; p; p>>=1,x=x*x%mod) if (p&1) ret=ret*x%mod;
    return ret;
}
ll get_inv(ll x){
    return ksm(x,mod-2);
}
#else
ll ksm(ll x,ll p){
    ll ret=1;
    for (; p; p>>=1,x=x*x) if (p&1) ret=ret*x;
    return ret;
}
#endif
 qpow 
#define N 1000005
#define M 5000005
int n,m,C,A,B,cnt,head[N],dis[N]; bool vis[N];
struct edge{ int to,nxt,v; }e[M];
void adde(int x,int y,int z){
    e[++cnt].to=y; e[cnt].nxt=head[x]; e[cnt].v=z;
    head[x]=cnt;
}
struct node{
    int dis,x; node(){}
    node(int a,int b){ dis=a,x=b; }
    bool operator < (const node &t) const{
        return dis>t.dis;
    }
};
#define local
int main(){
#ifdef local
    freopen("path.in","r",stdin); freopen("path.out","w",stdout);
#endif
    n=read(); m=read(); C=read();
    rep (i,1,m){
        int x=read(),y=read(),z=read();
        adde(x,y,z);
    }
    int len=0; for (; n; n>>=1) len++;
    A=read(),B=read();
    priority_queue<node> q; q.push(node(0,A));
    mset(dis,0x3f); dis[A]=0;
    while (!q.empty()){
        int u=q.top().x; q.pop();
        for (int i=head[u],v; i; i=e[i].nxt){
            v=e[i].to;
            if (dis[v]>dis[u]+e[i].v){
                dis[v]=dis[u]+e[i].v;
                q.push(node(dis[v],v));
            }
        }
        rep (i,0,len){
            int v=u^(1<<i);
            if (dis[v]>dis[u]+(1<<i)*C){
                dis[v]=dis[u]+(1<<i)*C;
                q.push(node(dis[v],v));
            }
        }
    }
    cout<<dis[B]<<endl;
    return 0;
}
// sample data:
/*
4 2 1
1 3 1
2 4 4
1 4

5

======
7 2 10
1 3 1
2 4 4
3 6

34
*/

// rest:
/*
异或的贡献是可以分开来计算的,,,
关于异或的边只需要在每一位上异或即可。。

*/

/*
If you find any bug in my code or solution, please tell me. Thanks so much.
email: 2411280037@qq.com
*/

总结

我好菜啊。

//ps.由于复制了一堆define代码略显冗长emm。。

//T4可能要,,以后再补。。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值