【2019.11.1】ZA

noip2012

Vigenère 密码

模拟

用的以前的方法 然后我康了康yyb的 发现我好菜

int r[30][30];
void pre(){
    for(int i=1;i<=26;++i)
        for(int j=0;j<=26-i;++j)
            r[i][i+j]=j+1;
    for(int i=2;i<=26;++i)
        for(int j=28-i;j<=26;++j)
            r[i][j-27+i]=j;
}

int main(){
#ifndef ONLINE_JUDGE
    freopen("in.txt","r",stdin);
#endif
    pre();
    scanf("%s%s",k,c);
    lk=strlen(k),lc=strlen(c);
    for(int i=0,cur=0,x,y,xx;i<lc;++i,++cur){
        if(cur>=lk) cur=0;xx=0;
        if(c[i]>='A'&&c[i]<='Z') x=c[i]-'A'+1;
        else if(c[i]>='a'&&c[i]<='z') xx=1,x=c[i]-'a'+1;
        if(k[cur]>='A'&&k[cur]<='Z') y=k[cur]-'A'+1;
        else if(k[cur]>='a'&&k[cur]<='z') y=k[cur]-'a'+1;
        if(xx) printf("%c",r[y][x]+96);
        else printf("%c",r[y][x]+64);
    }
    return 0;
}
char get(char a,char b){return (((b-97)-(a-97)+26)%26)+97;}
int main(){
    scanf("%s",k);scanf("%s",c);
    for(int i=0,x,l=strlen(c),lk=strlen(k);i<l;++i){
        x=0;
        if(c[i]>='A'&&c[i]<='Z') c[i]+=32,x=-32;
        if(k[i%lk]>='A'&&k[i%lk]<='Z') k[i%lk]+=32;
        putchar(get(k[i%lk],c[i])+x);
    }
    puts("");return 0;
}

国王游戏

贪心+高精

每个大臣获得的金币数分别为:排在该大臣前面的所有人的左手上的数的乘积除以他自己右手上的数 使获得奖赏最多的大臣尽可能少

对于国王身后两个点来分析 队列可能为

? \(L\) \(R\) \(L\) \(R\)

\(king\): \(a_0\) \(b_0\) \(king\): \(a_0\) \(b_0\)

\(P_1\): \(a_1\) \(b_1\) \(P_2\): \(a_2\) \(b_2\)

\(P_2\): \(a_2\) \(b_2\) \(P_1\): \(a_1\) \(b_1\)

\(ans1=max(\frac{a_0}{b1},\frac{a_0*a_1}{b_2})\) \(ans_2=max(\frac{a_0}{b_2},\frac{a_0*a_2}{b_1})\)

显然可以得到\(\frac{a_0*a_1}{b_2}>\frac{a_0}{b_2}\),\(\frac{a_0*a_2}{b_1}>\frac{a_0}{b_1}\)

若\(ans_1<ans_2\) 则\(\frac{a_0*a_2}{b_1}>\frac{a_0*a_1}{b_2}\) 即\(a_2*b_2>a_1*b_1\)

所以按\(a_i*b_i\)为关键字来排序就好

重温(?)高精

struct node{int a,b,c;}a[N];
bool cmp(node x,node y){return x.c<y.c;}

struct num{
    int a[N];
    num(){memset(a,0,sizeof(a));}
    num(int x){
        memset(a,0,sizeof(a));
        int t=0;
        while(x) a[++t]=x%base,x/=base;
        a[0]=t;
    }
    void print(){
        printf("%d",a[a[0]]);
        for(int i=a[0]-1;i;--i) printf("%04d",a[i]);
        puts("");
    }
}pai,p,nw,ans;
bool operator <(const num &p,const num &q){
    if(p.a[0]<q.a[0]) return 1;
    if(p.a[0]>q.a[0])  return 0;
    for(int i=p.a[0];i;--i) if(p.a[i]!=q.a[i]) return p.a[i]<q.a[i];
    return 0;
}
num operator +(const num &p,const num &q){
    num c;c.a[0]=Max(p.a[0],q.a[0]);
    for(int i=1;i<=c.a[0];++i)
        c.a[i]+=p.a[i]+q.a[i],c.a[i+1]+=c.a[i]/base,c.a[i]%=base;
    if(c.a[c.a[0]+1]) ++c.a[0];
    return c;
}
num operator -(const num &p,const num &q){
    num c=p;
    for(int i=1;i<=q.a[0];++i){
        c.a[i]-=q.a[i];
        if(c.a[i]<0) --c.a[i+1],c.a[i]+=base;
    }
    while(c.a[0]&&!c.a[c.a[0]]) --c.a[0];
    return c;
}
num operator *(const num &p,const num &q){
    num c;c.a[0]=p.a[0]+q.a[0]-1;
    for(int i=1;i<=p.a[0];++i)
        for(int j=1;j<=q.a[0];++j)
            c.a[i+j-1]+=p.a[i]*q.a[j],c.a[i+j]+=c.a[i+j-1]/base,c.a[i+j-1]%=base;
    while(c.a[c.a[0]+1]) ++c.a[0];
    return c;
}
num operator /(const num &p,const int &q){
    num x;x.a[0]=p.a[0];int y=0;
    for(int i=p.a[0];i;--i){
        y=y*base+p.a[i];
        if(y>=q) x.a[i]=y/q,y%=q;
    }
    while(x.a[0]&&!x.a[x.a[0]]) --x.a[0];
    return x;
}

int main(){
#ifndef ONLINE_JUDGE
    freopen("in.txt","r",stdin);
#endif
    rd(n);
    for(int i=0,x,y;i<=n;++i)  rd(x),rd(y),a[i]=(node){x,y,x*y};
    sort(a+1,a+n+1,cmp);
    pai=num(a[0].a);
    for(int i=1;i<=n;++i){
        p=num(a[i].a),q=a[i].b;
        nw=pai/q,pai=pai*p;
        if(ans<nw) ans=nw;
    }
    ans.print();
    return 0;
}

开车旅行

倍增

详细版

不仅记录当前元素的下一个元素\((next)\)还记录当前元素的上一个元素\((pre)\)

预处理出\(to[i][j],da[i][j],db[i][j]\)表示从\(i\)出发小\(A\)和小\(B\)经过\(2^j\)轮后到达的地点、小\(A\)走的路程、小\(B\)走的路程

预处理时询问第一近和第二近的地点用双向链表

双向链表

struct node{int h,id;}a[N];
bool cmp(node x,node y){return x.h<y.h;}

int pos[N][2],to[N][20];
void upd(int nw,int x){
    ll d=abs(h[nw]-a[x].h);
    if(dis[nw][0]>d||(dis[nw][0]==d&&a[x].h<h[pos[nw][0]]))
        dis[nw][1]=dis[nw][0],dis[nw][0]=d,pos[nw][1]=pos[nw][0],pos[nw][0]=a[x].id;
    else if(dis[nw][1]>d||(dis[nw][1]==d&&a[x].h<h[pos[nw][1]]))
        dis[nw][1]=d,pos[nw][1]=a[x].id;

}
void erase(int x){nxt[pre[x]]=nxt[x],pre[nxt[x]]=pre[x];}
void prepa(){
    for(int i=1,nw,l1,l2,r1,r2;i<=n;++i){
        nw=id[i],l1=pre[nw],l2=pre[l1],r1=nxt[nw],r2=nxt[r1];
        pos[i][0]=pos[i][1]=0,dis[i][0]=dis[i][1]=inf;
        if(l1&&l1!=n+1) upd(i,l1);
        if(l2&&l2!=n+1) upd(i,l2);
        if(r1&&r1!=n+1) upd(i,r1);
        if(r2&&r2!=n+1) upd(i,r2);
        erase(nw);
    }
    for(int i=1;i<=n;++i) to[i][0]=pos[pos[i][1]][0],da[i][0]=dis[i][1],db[i][0]=dis[pos[i][1]][0];
    for(int j=1;j<=17;++j)
        for(int i=1;i<=n;++i)
            to[i][j]=to[to[i][j-1]][j-1],da[i][j]=da[i][j-1]+da[to[i][j-1]][j-1],db[i][j]=db[i][j-1]+db[to[i][j-1]][j-1];
}

void query(int s,int lim,ll &A,ll &B){
    for(int i=17;i>=0;--i)
    if(to[s][i]&&da[s][i]+db[s][i]<=lim)
        lim-=da[s][i]+db[s][i],A+=da[s][i],B+=db[s][i],s=to[s][i];
    if(pos[s][1]&&dis[s][1]<=lim) A+=dis[s][1];
}

int main(){
#ifndef ONLINE_JUDGE
    freopen("in.txt","r",stdin);
#endif
    rd(n);
    for(int i=1;i<=n;++i) rd(h[i]),a[i]=(node){h[i],i};
    sort(a+1,a+n+1,cmp);
    for(int i=1;i<=n;++i) id[a[i].id]=i,pre[i]=i-1,nxt[i]=i+1;
    rd(x0),rd(m),pre[0]=nxt[n+1]=0,pre[n+1]=n,nxt[0]=1;
    prepa();
    ll A,B;double mn=inf,ret;int ans;
    for(int i=1;i<=n;++i){
        query(i,x0,A=0,B=0);
        if(!B) continue;
        ret=(A*1.0)/(B*1.0);
        if(mn>ret)  mn=ret,ans=i;
        else if(ret==mn) if(h[i]>h[ans]) ans=i;
    }
    printf("%d\n",ans);
    for(int i=1,s,lim;i<=m;++i){
        rd(s),rd(lim),A=0,B=0;
        query(s,lim,A,B);
        printf("%lld %lld\n",A,B);
    }
    return 0;
}

同余方程

换了一种写法ovo

void exgcd(ll a,ll b,ll &x,ll &y){
    if(b) exgcd(b,a%b,y,x),y-=x*(a/b);
    else x=1,y=0;
}
int main(){
#ifndef ONLINE_JUDGE
    freopen("in.txt","r",stdin);
#endif
    rd(A),rd(B);
    exgcd(A,B,x,y);
    printf("%lld",(x%B+B)%B);
    return 0;
}

借教室

数据结构

数组:支持随机访问,插入删除耗时多(静态、动态)
链表:不支持随机访问,插入删除耗时少(单向、双向)
栈:只在一端插入/删除/访问,后进先出(stack)三种主要操作:push, pop, top
队列:队首只删除/访问、队尾只插入,先进先出(queue、deque) 三种主要操作:push, pop, front

vector的使用&双线链表实现

struct L_t{
    L_t *prev,*next;
    L_t():prev(NULL),next(NULL){}
}*Head;

void insert(L_t *x,L_t *y){//把y插入x后面
    y->prev=x,y->next=x->next;
    y->prev->next=y,y->next->prev=y;
}
void erase(L_t *x){
    x->prev->next=x->next,
    x->next->prev=x->prev;
    //x->next=x->next->next,x->next->prev=x;
}
void resume(L_t *x){//恢复刚删除的x
    x->prev->next=x,
    x->next->prev=x;
}
void init(){
    Head=new L_t();
    Head->prev=Head->next=Head;
}

邻值查找

双向链表

struct node{int x,id;}a[N];
bool cmp(node x,node y){return x.x<y.x;}
int main(){
#ifndef ONLINE_JUDGE
    freopen("in.txt","r",stdin);
#endif
    rd(n);
    for(int i=1;i<=n;++i) rd(a[i].x),a[i].id=i;
    sort(a+1,a+n+1,cmp);a[0].x=-3000000000,a[n+1].x=3000000000;
    for(int i=1;i<=n;++i) id[a[i].id]=i,pre[i]=i-1,nxt[i]=i+1;
    for(int i=n,nw,l,r,lw,rw;i>=2;--i){
        nw=id[i],l=pre[nw],r=nxt[nw];
        lw=abs(a[nw].x-a[l].x),rw=abs(a[nw].x-a[r].x);
        if(lw<=rw)  ans[i]=make_pair(lw,a[l].id);
        else if(lw>rw) ans[i]=make_pair(rw,a[r].id);
        pre[nxt[nw]]=pre[nw],nxt[pre[nw]]=nxt[nw];
    }
    for(int i=2;i<=n;++i) printf("%d %d\n",ans[i].first,ans[i].second);
    return 0;
}

开车旅行

倍增

详细版

预处理出\(to[i][j],da[i][j],db[i][j]\)表示从\(i\)出发小\(A\)和小\(B\)经过\(2^j\)轮后到达的地点、小\(A\)走的路程、小\(B\)走的路程

预处理时询问第一近和第二近的地点用双向链表

双向链表

不仅记录当前元素的下一个元素\((next)\)还记录当前元素的上一个元素\((pre)\)

数组版:

int head,tail,tot;
struct Node{
    int value;
    int pre,nxt;
}node[SIZE];
int initialize(){//新建链表
    tot=2;
    head=1,tail=2;
    node[head].nxt=tail,node[tail].pre=head;
}
int insert(int p,int val){//在p后插入包含数据val的新节点
    q=++tot;
    node[q].value=val,node[node[q].nxt].pre=q,
    node[q].nxt=node[p].nxt,node[p].nxt=q,node[q].pre=p;
}
void remove(int p){
    node[node[p].pre].nxt=node[p].nxt,
    node[node[p].nxt].pre=node[p].pre;
}
void clear(){
    memset(node,0,sizeof(node));
    head=tail=tot=0;
}

邻值查找:给定一个长度为\(n\)的序列\(A\),\(A\)中的数各不相同。对于\(A\)中的每一个数 \(A_i\),求:\(min_{1≤j<i}|Ai?Aj|\)

以及令上式取到最小值的\(j\)(记为\(P_i\))。若最小值点不唯一,则选择使 AjAj 较小的那个。

int n,id[N],pre[N],nxt[N];
pair<int,int>ans[N];
template<class t>void rd(t &x){
    x=0;int w=0;char ch=0;
    while(!isdigit(ch)) w|=ch=='-',ch=getchar();
    while(isdigit(ch)) x=(x<<1)+(x<<3)+(ch^48),ch=getchar();
    x=w?-x:x;
}  

struct node{int x,id;}a[N];
bool cmp(node x,node y){return x.x<y.x;}
int main(){
#ifndef ONLINE_JUDGE
    freopen("in.txt","r",stdin);
#endif
    rd(n);
    for(int i=1;i<=n;++i) rd(a[i].x),a[i].id=i;
    sort(a+1,a+n+1,cmp);a[0].x=-3000000000,a[n+1].x=3000000000;
    for(int i=1;i<=n;++i) id[a[i].id]=i,pre[i]=i-1,nxt[i]=i+1;
    for(int i=n,nw,l,r,lw,rw;i>=2;--i){
        nw=id[i],l=pre[nw],r=nxt[nw];
        lw=abs(a[nw].x-a[l].x),rw=abs(a[nw].x-a[r].x);
        if(lw<=rw)  ans[i]=make_pair(lw,a[l].id);
        else if(lw>rw) ans[i]=make_pair(rw,a[r].id);
        pre[nxt[nw]]=pre[nw],nxt[pre[nw]]=nxt[nw];
    }
    for(int i=2;i<=n;++i) printf("%d %d\n",ans[i].first,ans[i].second);
    return 0;
}
struct Node{
    int value;
    Node *prev,next;
};
Node *head,*tail;
void initialize(){
    head=new Node(),tail=new Node();
    head->next=tail,tail->prev=head;
}
void insert(Node *p,int val){
    Node q=new Node(),q->value=val;
    p->next->prev=q,q->next=p->next,
    p->next=q,q->prev=p;
}
void remove(Node *p){
    p->prev->next=p->next,p->next->prev=p->prev;
}
void recycle(){
    while(head!=tail)
}

code

struct node{int h,id;}a[N];
bool cmp(node x,node y){return x.h<y.h;}

int pos[N][2],to[N][20];
void upd(int nw,int x){
    ll d=abs(h[nw]-a[x].h);
    if(dis[nw][0]>d||(dis[nw][0]==d&&a[x].h<h[pos[nw][0]]))
        dis[nw][1]=dis[nw][0],dis[nw][0]=d,pos[nw][1]=pos[nw][0],pos[nw][0]=a[x].id;
    else if(dis[nw][1]>d||(dis[nw][1]==d&&a[x].h<h[pos[nw][1]]))
        dis[nw][1]=d,pos[nw][1]=a[x].id;

}
void erase(int x){nxt[pre[x]]=nxt[x],pre[nxt[x]]=pre[x];}
void prepa(){
    for(int i=1,nw,l1,l2,r1,r2;i<=n;++i){
        nw=id[i],l1=pre[nw],l2=pre[l1],r1=nxt[nw],r2=nxt[r1];
        pos[i][0]=pos[i][1]=0,dis[i][0]=dis[i][1]=inf;
        if(l1&&l1!=n+1) upd(i,l1);
        if(l2&&l2!=n+1) upd(i,l2);
        if(r1&&r1!=n+1) upd(i,r1);
        if(r2&&r2!=n+1) upd(i,r2);
        erase(nw);
    }
    for(int i=1;i<=n;++i) to[i][0]=pos[pos[i][1]][0],da[i][0]=dis[i][1],db[i][0]=dis[pos[i][1]][0];
    for(int j=1;j<=17;++j)
        for(int i=1;i<=n;++i)
            to[i][j]=to[to[i][j-1]][j-1],da[i][j]=da[i][j-1]+da[to[i][j-1]][j-1],db[i][j]=db[i][j-1]+db[to[i][j-1]][j-1];
}

void query(int s,int lim,ll &A,ll &B){
    for(int i=17;i>=0;--i)
    if(to[s][i]&&da[s][i]+db[s][i]<=lim)
        lim-=da[s][i]+db[s][i],A+=da[s][i],B+=db[s][i],s=to[s][i];
    if(pos[s][1]&&dis[s][1]<=lim) A+=dis[s][1];
}

int main(){
#ifndef ONLINE_JUDGE
    freopen("in.txt","r",stdin);
#endif
    rd(n);
    for(int i=1;i<=n;++i) rd(h[i]),a[i]=(node){h[i],i};
    sort(a+1,a+n+1,cmp);
    for(int i=1;i<=n;++i) id[a[i].id]=i,pre[i]=i-1,nxt[i]=i+1;
    rd(x0),rd(m),pre[0]=nxt[n+1]=0,pre[n+1]=n,nxt[0]=1;
    prepa();
    ll A,B;double mn=inf,ret;int ans;
    for(int i=1;i<=n;++i){
        query(i,x0,A=0,B=0);
        if(!B) continue;
        ret=(A*1.0)/(B*1.0);
        if(mn>ret)  mn=ret,ans=i;
        else if(ret==mn) if(h[i]>h[ans]) ans=i;
    }
    printf("%d\n",ans);
    for(int i=1,s,lim;i<=m;++i){
        rd(s),rd(lim),A=0,B=0;
        query(s,lim,A,B);
        printf("%lld %lld\n",A,B);
    }
    return 0;
}

原文地址:https://www.cnblogs.com/lxyyyy/p/11779844.html

时间: 2024-09-30 19:09:13

【2019.11.1】ZA的相关文章

【2019.11.5】

2019.11.5 开方 可以找到规律der 然后特判 开方五次最大为\(2^{32}-1\) 注意可能有前导零 要注意特殊数据\(0,1\)== 然后我没有注意到\(1\)... 行叭我是瘟猪 int main(){ //freopen("sqrt.in","r",stdin); //freopen("sqrt.out","w",stdout); for(;scanf("%s",s+1)!=EOF;){

【2019.9.25】Za

容斥 容斥 \(\Big|\bigcup\limits_{i=1}^nS_i\Big|=\sum\limits_{m=1}^n(-1)^{m-1}\ \sum\limits_{a_i<a_{i+1}}\Big|\bigcap\limits_{i=1}^mS_{a_i}\Big|\) 不定方程非负整数解计数 不定方程\(\sum_{i=1}^n\ x_i=m\)和\(n\)个限制条件\(x_i\le b_i\) 没有限制时 其非负整数解为\(C_{m+n-1}^{m-1}\) 相当于有\(m\)个

【2019最新版】免接口!!涛舅舅轻奢版视频强制裂变程序,免公众号免备案域名!

轻奢版视频强制裂变程序[免接口版]正式上线,不需要认证公众号和备案域名! 优化防封和跳转逻辑,入口.落地.分享域名全部隔离 并加入针对微信IOS版的特殊防封策略! 除了分享卡片没有“小字描述”和“分享图标”以外,其他功能和[接口版]基本无差异! 轻奢版视频免接口版主要更新如下: 1.代码完全重构,大范围增强了程序的健壮性! 2.加入FuckXX脚本,禁止一切XX节点的访问,优化防封! 3.加入来路判断,非法访问将禁止,强化防封! 4.数据全部缓存化,前台完全避免对数据库的请求调用,所有数据调用全

【2019南京赛】

hello 2019:题意: 给出区间,要你在查询区间内有9102,同时没有8012的序列,需要删除多少个数字. 多次询问,所以给上我们的线段树. 这道题有原题: 我们dp表示i从状态i到状态j的操作次数, 我们定义0,1,2,3,4为"",2,20,201,2017的状态.对于每个状态用矩阵表示: 如dp[1][2]从状态为2到20: 例如我们看其中一个地方{ if(s[l]=='2') p[cur].a[0][0]=1,p[cur].a[0][1]=0; 表示此刻遇到了2,那么就0

【2017.11.07】noip赛前集训 | T1 遭遇【DP】

T1 遭遇 [题意] ??座楼房,立于城中. 第??座楼,高度???. 你需要一开始选择一座楼,开始跳楼.在第??座楼准备跳楼需要????的花费. 每次可以跳到任何一个还没有跳过的楼上去.但跳楼是有代价的,每次跳到另 外一座楼的代价是两座楼高度的差的绝对值,最后一次从楼上跳到地面上不需 要代价(只能跳到地上一次).为在代价不超过??的情况下,最多跳几次楼. (一座楼只能跳一次,且每次跳楼都要计算准备的花费) [题解] 跳楼时,楼房的高度是具有单调性的,所以先按照高度排序. f[i][j]表示已经

【2019最新资料】米尔iMX8M系列开发板MYD-JX8MX功能清单

2019年6月,米尔推出的基于NXP iMX8M系列芯片的开发平台MYD-JX8MX系列开发板,已开始量产.下面介绍这款开发板的功能:MYD-JX8MX 集成了丰富的外设资源,充分发挥了 i.MX8M 的产品性能,并定向目前主流产品应用提供了专用外设,主要特色资源如下:1.丰富的音视频接口(1) 双路视频输出:a.1 路为 HDMI 输出,支持 4K 分辨率高清输出b. 另一路由主芯片 MIPI-DSI 接口直接引出,同时在电路上将该 MIPI-DSI 转接为 LVDS 电路,客户根据屏幕情况二

【2016.11.18】进制转换

二进制:0.1       逢二进一    基数:2 需要用二进制来表示一个2 0.1 八进制:0~7        逢八进一    基数:8     2^3=8  一个八进制可以表示3位二进制 使用八进制表示8  10 0.1.2.3.4.5.6.7  表示8 (10)8 十进制:0~9        逢十进一    基数:10 0.1.2.3.4.5.6.7.8.9     表示10 10 十六进制:0~F      逢十六进一    基数:16    2^4 = 16  一个十六进制可以表

【2019.8.14】2019QB学堂DP图论班第一次考试 Problem C

Problem C Problem Description Tarzan 非常烦数轴因为数轴上的题总是难度非常大.不过他非常喜欢线段,因为有关线 段的题总是不难,讽刺的是在一个数轴上有 n 个线段,Tarzan 希望自己喜欢的东西和讨厌的 东西不在一起,所以他要把这些线段分多次带走,每一次带走一组,最多能带走 k 次.其实 就是要把这些线段分成至多 k 组,每次带走一组,问题远没有那么简单,tarzan 还希望每次 选择的线段组都很有相似性,我们定义一组线段的相似性是组内线段交集的长度,我们现在

【2019.10.18】luogu TG5动态规划进阶

树形dp P1352 没有上司的舞会 P2607 骑士(review) 对于每一个"联通快" 只有根节点有机会形成环 强制不选\(rt\)和\(rt\)的父亲 各跑一遍 P1131 时态同步(review) 贪心 显然增加深度约小的边越优 从下到上来调整 先将同一个点的儿子们延伸到一样 再往上进行一样的操作 //apio 烟火 树上背包? 一棵\(n\)个点的树,有点权.选择一个大小不超过\(K\)的联通块,使得点权和最大.\(n ≤ 2000\) \(f(x, i)\)表示\(x\)