【uoj#260】玩具谜题

传送门

http://uoj.ac/problem/260

分析

模拟。

int n,m;
int dir[N]; char nam[N][L];
int a[M],s[M];

int now;

int Go(int now,int dir1,int len) {
    int dirFin=(dir[now]^dir1);
    if (!dirFin) now-=len; else now+=len;
    now%=n; if (now<=0) now+=n;
    return now;
}

int main(void) {
    n=rd(),m=rd();
    rep(i,1,n) {
        dir[i]=rd();
        scanf("%s",nam[i]+1);
    }
    rep(i,1,m) a[i]=rd(),s[i]=rd();

    now=1;
    rep(i,1,m)
        now=Go(now,a[i],s[i]);
    printf("%s\n",nam[now]+1);
}

【uoj#261】天天爱跑步

题意

http://uoj.ac/problem/261

分析

我们考虑一条路径\((u,v)\)的影响。设\(u,v\)的LCA为\(anc\),每个节点的深度为\(dep\)。

那么,分两种情况讨论:

①当\(i\)在\(u,anc\)上时,路径\((u,v)\)对\(i\)产生影响,当且仅当

\(dep[u]-dep[i]=w[i]\)

参变分离得:\(dep[u]=dep[i]+w[i]\)

②当\(i\)在\(anc,v\)上时,路径\((u,v)\)对\(i\)产生影响,当且仅当

\(dep[u]-dep[anc]+dep[i]-dep[anc]=dep[u]-2*dep[anc]+dep[i]=w[i]\)

参变分离得:\(dep[u]-2*dep[anc]=w[i]-dep[i]\)

由于情况①与情况②类似,所以我们只要解决了情况①,情况②便迎刃而解。

所以我们现在解决情况①。

我们对于每个点\(i\),求出\(p[i]=dep[i]+w[i]\)。

枚举每条路径\((u,v)\),对于满足\(dep[u]=p[i]\)的所有点\(i\),若\(i\)在\((u,anc)\)上,那么答案+1。

这样直接均摊为\(O(n)\)???!!!

mdzz考场上我就栽在这里了。

复杂度是:\(\sum_{i=1}^{路径条数}\lbrace i|p[i]=当前路径的u\rbrace\)

均摊下来并不是\(O(n)\)的,而是\(O(n^2)\)的。

那怎么办?

我们把所有点按照\(p\)从小到大排序。

把路径按照\(dep[u]\)排序。

那么对于两条链,我们每次处理上下两端连续的信息,用two pointer实现。

那么,对于当前的一条路径,我们把\((u,anc)\)上的每个点的点权+1。

然后有多个单点查询点权是多少。

通过树链剖分+树状数组实现。

就这样少了60pt。

【uoj#262】换教室

待补充...

【uoj#263】组合数问题

传送门

http://uoj.ac/problem/263

多组询问,求\(\sum_{i=0}^n\sum_{j=0}^{\min(i,m)}[k|C_i^j],n,m\leq 2000,k\leq 21\)

分析

\(\sum_{i=0}^n\sum_{j=0}^{\min(i,m)}[k|C_i^j]\\=\sum_{i=0}^n\sum_{j=0}^m [k|C_i^j]\\=\sum_{i=0}^n\sum_{j=0}^m [k|{i!\over j!(i-j)!}]\)

记\(can(k,i,j)=[k|{i!\over j!(i-j)!}]\)

我们只要快速预处理出\(can\),再在\(O(n^2)\)内求出前缀和,就可以支持\(O(1)\)查询了。

设\(k\)的分解为\({a_1}^{p_1}{a_2}^{p_2}...{a_m}^{p_m}\),

\([k|x]=\prod_{i=1}^m[{a_i}^{p_i}|x]\)

所以我们把\(k\)分解,先求出\(cnt(k,i)=i的阶乘中素因子k的个数\),然后即可处理处\(can\)的值。

核心代码

int k;
int ret[B],ned[B],tot;

int cnt[N][B];
int can[N][N];
int sum[N][N];

int cas;
int n,m;

void Split(int x) {
    for (int i=2; i<=x; i++)
        if (x%i==0) {
            tot++;
            ret[tot]=i;
            ned[tot]=1;
            x/=i;
            while (x%i==0) ned[tot]++,x/=i;
        }
}

int Get(int x,int d) {
    int siz=0;
    while (x>0) {
        int t=x/d;
        siz+=t;
        x=t;
    }
    return siz;
}

int Check(int n,int m) {    // k|C(n,m) ???
    rep(b,1,tot) {
        int t=cnt[n][b]-cnt[m][b]-cnt[n-m][b];
        if (t<ned[b]) return 0;
    }
    return 1;
}

int main(void) {
    cas=rd(),k=rd();
    Split(k);

    rep(i,1,U_N) {
        rep(b,1,tot)
        cnt[i][b]=Get(i,ret[b]);
    }
    rep(i,0,U_N) rep(j,0,i)
    if (Check(i,j))
        can[i][j]=1;
    rep(i,0,U_N) rep(j,0,i) sum[i][j]=can[i][j];
    rep(i,1,U_N) sum[0][i]+=sum[0][i-1];
    rep(i,1,U_N) sum[i][0]+=sum[i-1][0];    //Get Border
    rep(i,1,U_N) {
        rep(j,1,U_N)
        sum[i][j]+=sum[i][j-1];
    }
    rep(i,1,U_N) {
        rep(j,1,U_N)
        sum[i][j]+=sum[i-1][j];
    }

    rep(tms,1,cas) {
        n=rd(),m=rd();
        int res=sum[n][m];
        printf("%d\n",res);
    }
}

【uoj#264】蚯蚓

传送门

http://uoj.ac/problem/264

分析

开始的时候被跳蚤吓到了...

因为跳蚤一般都是NOI难度的。

实际上被吓到了之后就太紧张了,简单的合并果子都不会做了,就这样又少了40pt。

然后发育畸形的\(m=0\)的蚯蚓导致我的输出也畸形了,又少了15pt。

很直观的想法就是用优先队列优化模拟。用delta记共同增量。

但是很明显会TLE。

发现自己还有一个特性没有使用:每次加入队列的是由原来的数生成的,而且一定会比原来小。

开三个单调队列。

队列1:原长

队列2:\(\lfloor px\rfloor\)队列

队列3:\(x-\lfloor px\rfloor\)队列

为什么单调?因为每次截出来的蚯蚓长度都是递减的。

类似于哈夫曼树的建立啊。

只不过Huffman树是两条单调队列的。

核心代码:优先队列

int n;
int a[N];

int m;
int u,v;
double p;
int q;

int t;
int del;
priority_queue<int> que;

int main(void) {
    n=rd();
    m=rd(),q=rd(),u=rd(),v=rd();
    p=(double)u/v;
    t=rd();
    rep(i,1,n) a[i]=rd();

    rep(i,1,n) que.push(a[i]);
    del=0;
    rep(tms,1,m) {
        int now=que.top();
        now+=del;
        que.pop();
        int a=(floor)(now*p),b=now-a;
        del+=q;
        que.push(a-del),que.push(b-del);
        if (tms%t==0) {
            printf("%d",now);
            if (tms+t>m) printf("\n");
            else printf(" ");
        }
    }
    rep(tms,1,n+m) {
        int now=que.top();
        now+=del;
        que.pop();
        if (tms%t==0) {
            printf("%d",now);
            if (tms+t>n+m) printf("\n");
            else printf(" ");
        }
    }
}

核心代码:单调队列

#include <cstdio>
#include <cstring>
#include <cctype>
#include <climits>
#include <cmath>
#include <algorithm>
using namespace std;

#define rep(i,a,b) for (int i=(a);i<=(b);i++)

typedef long long LL;

const int N=131072;
const int M=10000000;
const int MIN=INT_MIN;

int n,m,q,u,v,t;
int a[N];

int del;
struct Queue {
    int q[M]; int qh,qt;
    Queue(void) {
        memset(q,0,sizeof q);
        qh=1,qt=0;
    }
    void Add(int x) {
        q[++qt]=x;
    }
    void Pop(void) {
        q[qh++]=0;
    }
    int Top(void) {
        return q[qh];
    }
    int Empty(void) {
        return qh>qt;
    }
}q1,q2,q3;

int rd(void) {
    int x=0,f=1; char c=getchar();
    for (;!isdigit(c);c=getchar()) if (c=='-') f=-1;
    for (;isdigit(c);c=getchar()) x=x*10+c-'0';
    return x*f;
}

int cmp(int a,int b) {
    return a>b;
}

Queue *PreChosen(Queue *a,Queue *b,Queue *c) {
    int mx=MIN;
    if (!(*a).Empty())
        mx=max(mx,(*a).Top());
    if (!(*b).Empty())
        mx=max(mx,(*b).Top());
    if (!(*c).Empty())
        mx=max(mx,(*c).Top());
    if (!(*a).Empty()&&mx==(*a).Top())
        return a;
    else if (!(*b).Empty()&&mx==(*b).Top())
        return b;
    else return c;
}

int main(void) {
    #ifndef ONLINE_JUDGE
    freopen("uoj#264.in","r",stdin);
    freopen("uoj#264.out","w",stdout);
    #endif

    n=rd(),m=rd(),q=rd(),u=rd(),v=rd(),t=rd();
    rep(i,1,n) a[i]=rd();

    sort(a+1,a+n+1,cmp); rep(i,1,n) q1.Add(a[i]);
    rep(i,1,m) {
        Queue *now=PreChosen(&q1,&q2,&q3);
        int facLen=(*now).Top()+del; (*now).Pop();
        if (i%t==0) printf("%d ",facLen);
        del+=q; q2.Add((LL)facLen*u/v-del); q3.Add(facLen-(LL)facLen*u/v-del);
    }
    printf("\n");
    rep(i,1,n+m) {
        Queue *now=PreChosen(&q1,&q2,&q3);
        int facLen=(*now).Top()+del; (*now).Pop();
        if (i%t==0) printf("%d ",facLen);
    }
    printf("\n");

    return 0;
}

【uoj#265】愤怒的小鸟

传送门

http://uoj.ac/problem/265

分析

状压dp。

设\(f[S]\)表示打掉状态为\(j\)的猪的最小小鸟数。

由于所有鸟都要打掉,所以\(S\)中的状态转移为低位填满的。

转移有两种情况:①打掉一只 ②选择当前这只和另外一只打掉

转移方程自行脑补。

考场上由于精度问题少了20pt。

代码

#include <cstdio>
#include <cstring>
#include <cctype>
#include <cmath>
#include <algorithm>
using namespace std;

#define rep(i,a,b) for (int i=(a);i<=(b);i++)
#define per(i,a,b) for (int i=(a);i>=(b);i--)

const int N=32;
const int S=1048576;

const double EPS=1e-8;

int cas;

int n,m;
double x[N],y[N];

int full;
int f[S];

inline int rd(void)
{
    int x=0,f=1; char c=getchar();
    for (;!isdigit(c);c=getchar()) if (c=='-') f=-1;
    for (;isdigit(c);c=getchar()) x=x*10+c-'0';
    return x*f;
}

/*
a * xi * xi + b * xi = yi
a * xj * xj + b * xj = yj

a*(xi^2)*(xj^2) + b*xi*(xj^2) = yi*(xj^2)
a*(xi^2)*(xj^2) + b*(xi^2)*xj = yj*(xi^2)

b( xi*xj^2 - xi^2*xj ) = yi*(xj^2)-yj*(xi^2)

*/

inline int cmp(double a,double b)
{
    if (fabs(a-b)<EPS) return 0;
    return a<b?-1:1;
}

int Solve(double xi,double yi,double xj,double yj,double &a,double &b)
{
    double t=xi*xj*xj-xi*xi*xj; if (!cmp(t,0)) return 0;
    b=(yi*xj*xj-yj*xi*xi)/(xi*xj*xj-xi*xi*xj);
    a=(yi-xi*b)/(xi*xi);
    if (cmp(a,0)>=0) return 0; else return 1;
}

inline int OnLine(double xi,double yi,double a,double b)
{
    double t=a*xi*xi+b*xi;
    return !cmp(t,yi);
}

int main(void)
{
    #ifndef ONLINE_JUDGE
    freopen("angrybirds.in","r",stdin);
    freopen("angrybirds.out","w",stdout);
    #endif

    cas=rd();
    rep(tms,1,cas)
    {
        memset(x,0,sizeof x); memset(y,0,sizeof y);
        n=rd(),m=rd();
        rep(i,1,n) scanf("%lf%lf",x+i,y+i);

        full=(1<<n)-1;
        fill(f,f+full+1,n+1); f[0]=0;
        rep(st,0,full-1)    //从低位到高位,第1个空位
        {
            int bit=1; while (st>>(bit-1)&1) bit++;
            f[st|(1<<(bit-1))]=min(f[st|(1<<(bit-1))],f[st]+1);
            rep(i,bit+1,n) if (!(st>>(i-1)&1))
            {
                double a,b; int tag=Solve(x[bit],y[bit],x[i],y[i],a,b); if (!tag) continue;
                int nxST=st; rep(j,bit,n) if (OnLine(x[j],y[j],a,b)) nxST|=(1<<(j-1));
                f[nxST]=min(f[nxST],f[st]+1);
            }
        }
        printf("%d\n",f[full]);
    }

    return 0;
}

noip2016题解汇总的更多相关文章

  1. LeetCode All in One题解汇总(持续更新中...)

    突然很想刷刷题,LeetCode是一个不错的选择,忽略了输入输出,更好的突出了算法,省去了不少时间. dalao们发现了任何错误,或是代码无法通过,或是有更好的解法,或是有任何疑问和建议的话,可以在对 ...

  2. LeetCode题解汇总(包括剑指Offer和程序员面试金典,持续更新)

    LeetCode题解汇总(持续更新,并将逐步迁移到本博客列表中) LeetCode题解分类汇总(包括剑指Offer和程序员面试金典) 剑指Offer 序号 题目 难度 03 数组中重复的数字 简单 0 ...

  3. 历年NOIP选题题解汇总

    联赛前上vijos板刷往年联赛题,使用在线编辑编写代码,祝我rp++. 废话不多说,挑比较有意思的记一下. 题目是按照年份排序的,最早只到了03年. 有些题目因为 我还没写/很早之前写的忘了 所以就没 ...

  4. Noip2016题解&总结

    原文放在我的uoj博客上,既然新开了blog,那就移过来了 玩具谜题(toy) 送分题.没有什么好说的. 直接按照题目的要求模拟即可. 标准的noip式day1T1. #include<cstd ...

  5. bzoj题解汇总(1017-1020)

    bzoj1017: 树形dp. 设\(f[i][j][k]\)表示当前在点\(i\),有\(j\)个用于上层合成,花费金币为\(k\)的最大攻击力. bzoj1018: 一题多解. http://ww ...

  6. 网络流24(san)题题解汇总

    开坑(烂尾预定 1.餐巾计划问题 题解 2.最小路径覆盖问题 题解 3.试题库问题 题解 4.[CTSC1999]家园 题解 5.骑士共存问题 题解 6.最长不下降子序列问题 题解 7.深海机器人问题 ...

  7. LibreOJ 题解汇总

    目录 #1. A + B Problem #2. Hello, World! #3. Copycat #4. Quine #7. Input Test #100. 矩阵乘法 #101. 最大流 #10 ...

  8. [NOIP补坑计划]NOIP2016 题解&做题心得

    感觉16年好难啊QAQ,两天的T2T3是不是都放反了啊…… 场上预计得分:100+80+100+100+65+100=545(省一分数线280) ps:loj没有部分分,部分分见洛咕 题解: D1T1 ...

  9. CCPC、Petrozavodsk Camp、OpenCup 题解汇总

    省赛 \([\text{2021.11.30}]\) 2021 Jilin Collegiate Programming Contest 全部完成. \([\text{2021.12.25}]\) 2 ...

随机推荐

  1. c++学习笔记2--constexpr,类型别名,auto

    constexpr:修饰常量表达式,约定修饰对象不仅为常量,而且在编译阶段就能得到值. 与const不同的是,constexpr约束的是当事人,就是说,constexpr int *a=1;这样的语句 ...

  2. 关于htons和htonl

    htons的功能:将一个无符号短整型数值转换为网络字节序,即大端模式(big-endian) 参数u_short hostshort: 16位无符号整数 返回值:TCP / IP网络字节顺序. hto ...

  3. 适配 iOS尺寸

    http://liumh.com/2015/10/21/ios-image-related-matching/ 苹果IPHONE 5主屏尺寸: 4英寸 屏幕尺寸: iPhone 6 Plus 5.5英 ...

  4. Android 路径大全

    1 内部存储路径为/data/data/youPackageName/ 目录结构 //返回cache文件对象 this.getCacheDir(); //返回databases下指定文件 this.g ...

  5. Dev gridview新增一行自动获得焦点并打开编辑模式

    1.gridview添加一行自动获得焦点实现方式: 关键代码: GarsonZhang dt.Rows.Add("1", "2"); gridView1.Foc ...

  6. FreeSWITCH 1.6关于视频通话的一些测试

    简单的测试了一下,暂时没把精力放到这一块. ① 视频编码透传的设置(使用代理模式). 修改internal.xml文件的以下参数: <param name="inbound-proxy ...

  7. [51NOD1007] 正整数分组(DP,记忆化搜索)

    题目链接:http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1007 dp(id, s)表示第id个数之前,其中一个集合和为s ...

  8. IP地址验证

    /** * 验证IP地址 * * @param 待验证的字符串 * @return 如果是符合格式的字符串,返回 <b>true </b>,否则为 <b>false ...

  9. jsp利用cookie记住用户名,下次登录时显示在文本框中(仅仅一个Cookie就整了将近三个小时,⊙﹏⊙b汗)

    <%@page import="java.net.URLDecoder"%> <%@page import="sun.security.util.Len ...

  10. [C和指针]第五部分

    声明:原创作品,转载时请注明文章来自SAP师太技术博客( 博/客/园www.cnblogs.com):www.cnblogs.com/jiangzhengjun,并以超链接形式标明文章原始出处,否则将 ...