论蒟蒻如何被cf虐

以下是身败名裂后的题解菌===========

Div1 A.Watchmen

有n个点,每个点有一个坐标。求曼哈顿距离=欧几里得距离的点对数量。

只需要统计x或y一样的点对数量。容斥即可。注意long long。(sad story

//By zzq
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <algorithm>
#include <string.h>
#include <math.h>
#include <set>
#include <map>
using namespace std;
int n;
typedef long long ll;
pair<int,int> sb[233333];
int main()
{
scanf("%d",&n);
for(int i=1;i<=n;i++) scanf("%d%d",&sb[i].first,&sb[i].second);
sort(sb+1,sb+1+n);
ll x=0,y=0,xy=0;
for(int i=1;i<=n;i++)
{
int tot;
for(int j=i;j<=n;j++)
{
if(sb[j].first!=sb[i].first||sb[j].second!=sb[i].second) break;
tot=j;
}
xy+=(ll)(tot-i)*(tot-i+1)/2;
i=tot;
}
for(int i=1;i<=n;i++)
{
int tot;
for(int j=i;j<=n;j++)
{
if(sb[j].first!=sb[i].first) break;
tot=j;
}
x+=(ll)(tot-i)*(tot-i+1)/2;
i=tot;
}
for(int i=1;i<=n;i++) swap(sb[i].first,sb[i].second);
sort(sb+1,sb+1+n);
for(int i=1;i<=n;i++)
{
int tot;
for(int j=i;j<=n;j++)
{
if(sb[j].first!=sb[i].first) break;
tot=j;
}
y+=(ll)(tot-i)*(tot-i+1)/2;
i=tot;
}
cout<<x+y-xy<<"\n";
}

Div1 B.Image Preview

你的手机上有n张照片,相册是那种翻页的,也就是说你从i张照片向右翻,如果i=n,就会翻到第一张,否则翻到i+1张,向左翻类似。你翻一张照片要a的时间,然后有一些照片是横着的(w),有些是竖着的(h),如果照片是横着的,那么看前就要先旋转,旋转一张要b的时间。看一张照片要1的时间。开始你打开了第一张照片,你每打开一张没看过的照片就必须要看掉,总共有T的时间,问你最多能看几张照片。

题解:

比如n=7:1 2 3 4 5 6 7

可能会有如下几种方法是最优的:

(1) 1 2 3 4 5 类似这样从左往右直接看

(2) 1 2 3 2 1 7 6 5 先往右看几张,往回翻,再从n张开始往回看

(3) 1 7 6 5 6 7 1 2 3 看完第一张,先往左翻,往回看几张,再翻回第一张,再往右看几张

然后我们只要预处理出从第一张开始往后多少张要花多少时间,从最后一张往前多少张要花多少时间,然后分这三种情况二分或者尺取即可。因为懒所以用了二分…(最后交了五六次才过)

//By zzq
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <algorithm>
#include <string.h>
#include <math.h>
#include <set>
#include <map>
using namespace std;
typedef long long ll;
ll n,a,b,T,sl[2333333],sr[2333333];
char w[233333];
int main()
{
scanf("%I64d%I64d%I64d%I64d",&n,&a,&b,&T);
scanf("%s",w+1);
int ans=0;
{
ll ct=0;
for(int i=1;i<=n;i++)
{
char cp=w[i]; ll tm=1+a;
if(cp=='w') tm+=b;
ct+=tm; sl[i]=ct;
if(ct-a<=T) ans=max(ans,i);
}
}
{
ll ct=0;
for(int i=n;i>=1;i--)
{
char cp=w[i]; ll tm=1+a;
if(cp=='w') tm+=b;
ct+=tm; sr[i]=ct;
}
}
for(int i=1;i<=n;i++)
{
ll zbt=sl[i]+(i-2)*a;
if(zbt>T) continue;
int l=i+1,r=n+1;
while(l<r)
{
int mid=(l+r)>>1;
ll ct=zbt+sr[mid];
if(ct<=T) r=mid; else l=mid+1;
}
if(r==n+1) continue;
ans=max(ans,int(n-l+1+i));
}
for(int i=1;i<=n;i++)
{
ll zbt=sr[i]+(n-i)*a;
if(zbt>T) continue;
int l=0,r=i-1;
while(l<r)
{
int mid=(l+r+1)>>1;
ll ct=zbt+sl[mid];
if(ct<=T) l=mid; else r=mid-1;
}
if(r==0) continue;
ans=max(ans,int(n-i+1+l));
}
printf("%d\n",ans);
}

Div1 C.Table Compression

给你一个n*m的矩阵a,里面都是正整数,求一个正整数矩阵b使b中的最大数最小。对于每一行,a和b的相对顺序不变(即对于第i行,如果a[i][x]<a[i][y],那么b[i][x]<b[i][y],如果a[i][x]=a[i][y],那么b[i][x]=b[i][y],如果a[i][x]>a[i][y],那么b[i][x]>b[i][y]),每一列的相对顺序也不变。求一个最大数最小的b,多解输出任意一个。

每行每列排序,并查集缩一样的点,然后小于号连边,缩成DAG,跑一个类似拓扑排序的记忆化搜索即可。(我真的不知道怎么称呼这玩意儿

//By zzq
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <algorithm>
#include <string.h>
#include <math.h>
#include <set>
#include <map>
using namespace std;
#define SZ 4333333
int n,m,gf[SZ],a[SZ];
#define ID(i,j) (((i)-1)*m+(j)-1)
typedef pair<int,int> pii;
pii ps[SZ];
int ff(int x) {return gf[x]?gf[x]=ff(gf[x]):x;}
void unionn(int a,int b)
{
int ga=ff(a),gb=ff(b);
if(ga!=gb) gf[ga]=gb;
}
int M=0,ma[SZ],mb[SZ];
int MM=0,fst[SZ],nxt[SZ],vb[SZ];
void adde(int a,int b)
{
++MM; nxt[MM]=fst[a]; fst[a]=MM; vb[MM]=b;
}
int dep[SZ]; bool vis[SZ];
int gd(int x)
{
if(vis[x]) return dep[x];
int mn=0;
for(int e=fst[x];e;e=nxt[e])
{
int b=vb[e];
mn=max(mn,gd(b));
}
vis[x]=1; return dep[x]=mn+1;
}
int main()
{
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++)
{
for(int j=1;j<=m;j++) scanf("%d",&a[ID(i,j)]);
}
for(int i=1;i<=n;i++)
{
int pn=0;
for(int j=1;j<=m;j++) ps[++pn]=pii(a[ID(i,j)],j);
sort(ps+1,ps+1+pn);
for(int j=2;j<=pn;j++)
{
pii lst=ps[j-1],cur=ps[j];
int i1=ID(i,lst.second),i2=ID(i,cur.second);
if(lst.first==cur.first) unionn(i1,i2);
else ++M, ma[M]=i2, mb[M]=i1; //i1<i2
}
}
for(int j=1;j<=m;j++)
{
int pn=0;
for(int i=1;i<=n;i++) ps[++pn]=pii(a[ID(i,j)],i);
sort(ps+1,ps+1+pn);
for(int i=2;i<=pn;i++)
{
pii lst=ps[i-1],cur=ps[i];
int i1=ID(lst.second,j),i2=ID(cur.second,j);
if(lst.first==cur.first) unionn(i1,i2);
else ++M, ma[M]=i2, mb[M]=i1; //i1<i2
}
}
for(int i=1;i<=M;i++)
{
int a=ma[i],b=mb[i];
int f1=ff(a),f2=ff(b);
adde(f1,f2);
}
for(int i=1;i<=n;i++)
{
for(int j=1;j<=m;j++) gd(ff(ID(i,j)));
}
for(int i=1;i<=n;i++)
{
for(int j=1;j<=m;j++) printf("%d ",dep[ff(ID(i,j))]);
printf("\n");
}
}

Div1 D.Zip-line

给一个长度为n的序列h和m次询问。每次询问要求把一个位置上的数改成某一个值,询问LIS。询问互相独立。

考虑新的LIS中存不存在被修改的元素。

如果存在。因为询问可以离线,我们把询问排个序,在求LIS的时候顺便求一下带上这个修改后的元素的LIS。

如果不存在。如果LIS必须经过这个元素,那么长度就会-1,否则不变。

我们用L[i]表示以i结尾的LIS长度,R[i]表示以i开头的LIS长度。

那么设整个序列LIS为p,如果L[x]+R[x]-1=p那么x至少在一个LIS中对吧。那么如果x至少存在于一个LIS中且不存在其他的j使得L[j]=L[x],那么LIS的第L[x]位就必须为x。

#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <algorithm>
#include <string.h>
#include <vector>
#include <limits>
#include <set>
#include <map>
using namespace std;
int inf=1000000000;
#define SZ 666666
int n,a[SZ],len,lt[SZ],L[SZ],R[SZ],q,ql[SZ],qr[SZ],col[SZ];
struct Tuple {int a,b,id;} qs[SZ];
bool c1(Tuple a,Tuple b) {return a.a<b.a;}
bool c2(Tuple a,Tuple b) {return a.a>b.a;}
bool c3(Tuple a,Tuple b) {return a.id<b.id;}
int main()
{
scanf("%d%d",&n,&q);
for(int i=1;i<=n;i++) scanf("%d",a+i);
for(int i=1;i<=q;i++) scanf("%d %d",&qs[i].a,&qs[i].b), qs[i].id=i;
int cur;
sort(qs+1,qs+1+q,c1);
cur=1; len=0;
memset(lt,0,sizeof(lt));
for(int i=1;i<=n;i++)
{
int cl;
while(cur<=q&&qs[cur].a==i)
{
int ans,c=qs[cur].b;
if(!len||c>lt[len]) ans=len+1;
else ans=lower_bound(lt+1,lt+1+len,c)-lt;
ql[qs[cur].id]=ans;
++cur;
}
if(i!=1)
{
if(a[i]>lt[len]) lt[cl=++len]=a[i];
else lt[cl=lower_bound(lt+1,lt+1+len,a[i])-lt]=a[i];
}
else lt[1]=a[1], cl=1, len=1;
L[i]=cl;
}
int lis=len;
sort(qs+1,qs+1+q,c2);
for(int i=1;i<=n;i++) a[i]=inf-a[i];
cur=1; len=0;
memset(lt,0,sizeof(lt));
for(int i=n;i>=1;i--)
{
int cl;
while(cur<=q&&qs[cur].a==i)
{
int ans,c=inf-qs[cur].b;
if(!len||c>lt[len]) ans=len+1;
else ans=lower_bound(lt+1,lt+1+len,c)-lt;
qr[qs[cur].id]=ans;
++cur;
}
if(i!=n)
{
if(a[i]>lt[len]) lt[cl=++len]=a[i];
else lt[cl=lower_bound(lt+1,lt+1+len,a[i])-lt]=a[i];
}
else lt[1]=a[n], cl=1, len=1;
R[i]=cl;
}
for(int i=1;i<=n;i++)
{
if(L[i]+R[i]-1!=lis) continue;
col[L[i]]++;
}
sort(qs+1,qs+1+q,c3);
for(int p=1;p<=q;p++)
{
int i=qs[p].a;
int a1=ql[p]+qr[p]-1;
bool met=L[i]+R[i]-1==lis&&col[L[i]]==1;
int a2=lis-met;
printf("%d\n",max(a1,a2));
}
}

E题施工中…

CF#345 (Div1)的更多相关文章

  1. CF #345 Div1 D Zip-line

    题目链接:http://codeforces.com/contest/650/problem/D 大意是给一个数组,若干询问,每一次把一个数字改为另一个数字,问当前数组最长上升子序列,询问之间是独立的 ...

  2. CF#462 div1 D:A Creative Cutout

    CF#462 div1 D:A Creative Cutout 题目大意: 原网址戳我! 题目大意: 在网格上任选一个点作为圆中心,然后以其为圆心画\(m\)个圆. 其中第\(k\)个圆的半径为\(\ ...

  3. CF #356 div1 A. Bear and Prime 100

    题目链接:http://codeforces.com/contest/679/problem/A CF有史以来第一次出现交互式的题目,大致意思为选择2到100中某一个数字作为隐藏数,你可以询问最多20 ...

  4. 【Codeforces】#345 Div1

    1. Watchmen1.1 题目描述给$n$个点,求曼哈顿距离等于欧式距离的点对数. 1.2 基本思路由$|x_i-x_j|+|y_i-yj| = \sqrt{(x_i-x_j)^2+(y_i-yj ...

  5. CF#345 div2 A\B\C题

    A题: 贪心水题,注意1,1这组数据,坑了不少人 #include <iostream> #include <cstring> using namespace std; int ...

  6. CF #228 div1 B. Fox and Minimal path

    题目链接:http://codeforces.com/problemset/problem/388/B 大意是用不超过1000个点构造一张边权为1的无向图,使得点1到点2的最短路的个数为给定值k,其中 ...

  7. CF #349 div1 B. World Tour

    题目链接:http://codeforces.com/problemset/problem/666/B 大意是给一张有向图,选取四个点,使得走这四个点,任意两个点之间走最短路,总距离最长. 3000个 ...

  8. CF #335 div1 A. Sorting Railway Cars

    题目链接:http://codeforces.com/contest/605/problem/A 大意是对一个排列进行排序,每一次操作可以将一个数字从原来位置抽出放到开头或结尾,问最少需要操作多少次可 ...

  9. CF #299 div1 B. Tavas and Malekas KMP-next数组

    题目链接:http://codeforces.com/contest/536/problem/B 一个原始字符串,一个未知字符串,每一次从pos[i]开始覆盖未知字符串,问最后字符串的形式,以及判断过 ...

随机推荐

  1. 两个Service之间相互监视的实现

    在实际开发中可能需要用到两个Service相互监视的情况,本示例就是实现此功能以作参考. 服务A: public class ServiceA extends Service { private st ...

  2. Token原理以及应用

    近期由于项目需要开发供第三方使用的api,在整个架构设计的一个环节中,对api访问需要进行认证,在这里我选择了token认证. 一:token的优势(此部分引自http://www.sumahe.cn ...

  3. (视频)《快速创建网站》 4.1 为啥造软件不同于造汽车,为啥是软件就一定会有Bug - 构建开发运维一体化(DevOps)

    本文是<快速创建网站>系列的第9篇,如果你还没有看过之前的内容,建议你点击以下目录中的章节先阅读其他内容再回到本文. 访问本系列目录,请点击:http://devopshub.cn/tag ...

  4. BIEE 目录迁移(文件夹)方式

    文件夹迁移方式一(归档--取消归档):     归档:analytics中选择目录,定位至指定文件夹,更多中选择归档,保存为 .catalog文档:     释放归档: 进入目录管理器,离线方式登陆, ...

  5. Linux账户密码过期安全策略设置

    在Linux系统管理中,有时候需要设置账号密码复杂度(长度).密码过期策略等,这个主要是由/etc/login.defs参数文件中的一些参数控制的的.它主要用于用户账号限制,里面的参数主要有下面一些: ...

  6. mysql5.6主从参数详解

    mysql5.6的主从相当的不错,增加了不少参数,提升了主从同步的安全和效率,以下是mysql5.6主从参数详解. 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 ...

  7. oops call trace 解析

    Call Trace: [  221.634988]  [<ffffffff8103fbc7>] ? kmld_pte_lookup+0x17/0x60 [  221.635016]  [ ...

  8. 必须知道的八大种排序算法【java实现】(二) 选择排序,插入排序,希尔算法【详解】

    一.选择排序 1.基本思想:在要排序的一组数中,选出最小的一个数与第一个位置的数交换:然后在剩下的数当中再找最小的与第二个位置的数交换,如此循环到倒数第二个数和最后一个数比较为止. 2.实例 3.算法 ...

  9. 贤者时间太久了么?--MySQL继续玩

    hi 给自己放了大概三天的假,没有一点点防备,没有一点点准备,无意的 是不是贤者时间过不去了我不知道啊...继续看东西吧 1.MySQL -----运算符和函数----- 字符函数,数值运算符,比较运 ...

  10. HttpURLConnection用法详解

    针对JDK中的URLConnection连接Servlet的问题,网上有虽然有所涉及,但是只是说明了某一个或几个问题,是以FAQ的方式来解决的,而且比较零散,现在对这个类的使用就本人在项目中的使用经验 ...