A.Chain Reaction(DP+二分)

题意:一排有n个灯塔,每个灯塔给出坐标xi和力量yi,
每次从最右边依次点亮灯塔,每点亮一个灯塔,它左边的距离它yi范围内的灯塔将受到损坏。
现在允许在最右边>max(xi)处添加一座力量值yi的灯塔。
问最少只会损坏多少灯塔。

分析:因为我们是从右边点亮灯塔的,所以我们点亮我们添加的那座灯塔只会损坏连续个灯塔。最后就相当于从末尾的某一个灯塔开始点亮。
我们令dp[i]表示点亮第i座灯塔最少损坏多少灯塔。
于是我们对于每个dp[i],二分可以得到他前面的前驱。
所以dp[i]=dp[j]+1(j<i).
注意题目给出的灯塔并不是有序的,需要排序一遍。

# include <stdio.h>
# include <string.h>
# include <stdlib.h>
# include <iostream>
# include <vector>
# include <queue>
# include <stack>
# include <map>
# include <math.h>
# include <algorithm>
using namespace std;
# define lowbit(x) ((x)&(-x))
# define pi acos(-1.0)
# define MAXN
# define eps 1e-
# define MAXM
# define MOD
# define INF
# define mem(a,b) memset(a,b,sizeof(a))
# define FOR(i,a,n) for(int i=a; i<=n; ++i)
# define FO(i,a,n) for(int i=a; i<n; ++i)
# define bug puts("H");
# define lch p<<,l,mid
# define rch p<<|,mid+,r
# pragma comment(linker, "/STACK:1024000000,1024000000")
typedef long long LL;
typedef unsigned long long ULL;
int _MAX(int a, int b){return a>b?a:b;}
int _MIN(int a, int b){return a>b?b:a;}
int Scan() {
int res=, flag=;
char ch;
if((ch=getchar())=='-') flag=;
else if(ch>=''&&ch<='') res=ch-'';
while((ch=getchar())>=''&&ch<='') res=res*+(ch-'');
return flag?-res:res;
}
void Out(int a) {
if(a<) {putchar('-'); a=-a;}
if(a>=) Out(a/);
putchar(a%+'');
} int a[][], sum[]; int comp(const void * b, const void * c){return *(int *)b-*(int *)c;}
int main ()
{
int n;
scanf("%d",&n);
FOR(i,,n) scanf("%d%d",&a[i][],&a[i][]);
qsort(a+,n,sizeof(a[]),comp);
sum[]=;
FOR(i,,n) {
int l=, r=i, mid;
while (l<r) {
mid=(l+r)>>;
if (l==mid) break;
if (a[mid][]<a[i][]-a[i][]) l=mid;
else r=mid;
}
sum[i]=+sum[l];
}
int ans=;
FOR(i,,n) ans=max(ans,sum[i]);
printf("%d\n",n-ans);
return ;
}

B.Zuma(区间DP)

给出一串n个数字(n<=500).每次操作可以消掉一个回文串。然后补齐。
问最少需要操作多少次。

姿势很优雅的区间DP;
很容易想到dp[l][r]表示消掉[l,r]的回文串最少需要多少步。
但是在转移的过程中GG了,假如它先消中间的某一部分,然后再对齐再消,这样咋办。
于是我码了一个暴力判断字符串是否回文。结果TLE了。
仔细一想,因为1个数字显然是回文串。
对于[l,r]区间,我们枚举[l+1,r]内的一个k使得a[k]==a[l],这时候我们可以先消[l+1,k-1].
再消a[l]和a[k],我们注意到消[l+1,k-1]的最后一步一定会变成一个回文串,
因为a[l]==a[k], 所以我们消a[l,k]的步数就等于a[l+1,k-1].
即dp[l][k]==dp[l+1][k-1].
所以状态转移方程就是dp[l][r]=min(dp[l+1][r]+1,dp[l+1][k-1]+dp[k+1][r])(a[k]==a[l])
最后判断一下边界就行了。

# include <stdio.h>
# include <string.h>
# include <stdlib.h>
# include <iostream>
# include <vector>
# include <queue>
# include <stack>
# include <map>
# include <math.h>
# include <algorithm>
using namespace std;
# define lowbit(x) ((x)&(-x))
# define pi acos(-1.0)
# define MAXN
# define eps 1e-
# define MAXM
# define MOD
# define INF
# define mem(a,b) memset(a,b,sizeof(a))
# define FOR(i,a,n) for(int i=a; i<=n; ++i)
# define FO(i,a,n) for(int i=a; i<n; ++i)
# define bug puts("H");
# define lch p<<,l,mid
# define rch p<<|,mid+,r
# pragma comment(linker, "/STACK:1024000000,1024000000")
typedef long long LL;
typedef unsigned long long ULL;
int _MAX(int a, int b){return a>b?a:b;}
int _MIN(int a, int b){return a>b?b:a;}
int Scan() {
int res=, flag=;
char ch;
if((ch=getchar())=='-') flag=;
else if(ch>=''&&ch<='') res=ch-'';
while((ch=getchar())>=''&&ch<='') res=res*+(ch-'');
return flag?-res:res;
}
void Out(int a) {
if(a<) {putchar('-'); a=-a;}
if(a>=) Out(a/);
putchar(a%+'');
} int n, a[], dp[][]; int dfs(int l, int r)
{
if (~dp[l][r]) return dp[l][r];
if (l>r) return ;
if (l==r) return dp[l][r]=;
int ans=INF;
ans=min(ans,dfs(l+,r)+);
FOR(i,l+,r) {
if (a[i]==a[l]) {
if (i==r) ans=min(ans,dfs(l+,i-));
else if (i==l+) ans=min(ans,dfs(i+,r)+);
else ans=min(ans,dfs(l+,i-)+dfs(i+,r));
}
}
return dp[l][r]=ans;
}
int main ()
{
mem(dp,-);
scanf("%d",&n);
FOR(i,,n) scanf("%d",a+i);
dfs(,n);
printf("%d\n",dp[][n]);
return ;
}

C.Marbles(脑洞+hash)

#include <bits/stdc++.h>
using namespace std; typedef long long LL;
typedef unsigned long long ULL;
const LL INF = 1E9+;
const int MI = ~0u>>; int main()
{
int n;
string s1,s2;
cin>>n>>s1>>s2;
n--;
for(int i=;i<n;i++)
{
switch(s2[i])
{
case 'N':s2[i]='S';break;
case 'S':s2[i]='N';break;
case 'W':s2[i]='E';break;
case 'E':s2[i]='W';break;
}
}
ULL v1=,v2=;
const ULL seed=;
ULL wt=;
for(int i=n-;i>=;i--,wt*=)
{
v1=v1+(s1[i]-'a')*wt;
v2=v2*seed+s2[i]-'a';
if(v1==v2)
{
printf("NO");
return ;
}
}
printf("YES");
return ;
}

D.Power Tree(线段树维护dfn+逆元)

分析: 我们可以算出每一个节点对根节点的贡献因子mi。
即di是节点i的儿子节点数+1.
实际上mi就是从i到根节点的简单路径上的di的乘积。
当新加入一个节点u到节点p时。我们观察可以发现,仅仅改变了p和p的子树的mi。
显然是mi=mi*(dp+1)/dp. mu=mp。
我们需要一个数据结构可以 对一个区间进行乘,更新一个值,以及求一个区间的总和。
我们用线段树维护dfn序。
那么一个节点的子树就是一段连续的区间。
我们求一个节点的贡献时。显然就是sum同时除以他们的公共路径的mi。
由于乘法是一个浮点数。我们先累乘所有的分子,再累乘所有的分母,最后我们用乘法逆元
可以求出取模。

代码量有点受不了。。。

#include <cstdio>
#include <vector>
#include <algorithm>
#pragma comment(linker, "/STACK:16000000")
using namespace std; typedef long long ll; const int mod = ;
const int Maxn = ;
const int Maxm = ; int n, q;
int val[Maxn];
int a[Maxn], b[Maxn], c[Maxn];
vector <int> neigh[Maxn];
int ch[Maxn];
int P[Maxn], cur, L[Maxn], R[Maxn];
int mult[Maxm];
int fl[Maxm], sum[Maxm]; void Traverse(int v)
{
L[v] = ++cur;
for (int i = ; i < neigh[v].size(); i++)
Traverse(neigh[v][i]);
R[v] = cur;
} void createMult(int v, int l, int r)
{
mult[v] = ;
if (l < r) {
int m = l + r >> ;
createMult( * v, l, m); createMult( * v + , m + , r);
}
} void updMult(int v, int l, int r, int a, int b, int val)
{
if (l == a && r == b) mult[v] = ll(mult[v]) * val % mod;
else {
int m = l + r >> ;
if (a <= m) updMult( * v, l, m, a, min(m, b), val);
if (m + <= b) updMult( * v + , m + , r, max(m + , a), b, val);
}
} int getMult(int v, int l, int r, int x)
{
int res = mult[v];
if (l < r) {
int m = l + r >> ;
if (x <= m) res = ll(res) * getMult( * v, l, m, x) % mod;
else res = ll(res) * getMult( * v + , m + , r, x) % mod;
}
return res;
} void Union(int v)
{
sum[v] = (sum[ * v] + sum[ * v + ]) % mod;
} void downOn(int v, int val)
{
fl[v] = ll(fl[v]) * val % mod;
sum[v] = ll(sum[v]) * val % mod;
} void Down(int v)
{
if (fl[v] != ) {
downOn( * v, fl[v]); downOn( * v + , fl[v]);
fl[v] = ;
}
} void createSum(int v, int l, int r)
{
fl[v] = ;
if (l == r) sum[v] = val[l];
else {
int m = l + r >> ;
createSum( * v, l, m); createSum( * v + , m + , r);
Union(v);
}
} int getSum(int v, int l, int r, int a, int b)
{
if (l == a && r == b) return sum[v];
else {
Down(v);
int m = l + r >> ;
int res = ;
if (a <= m) res = (res + getSum( * v, l, m, a, min(m, b))) % mod;
if (m + <= b) res = (res + getSum( * v + , m + , r, max(m + , a), b)) % mod;
return res;
}
} void multSum(int v, int l, int r, int a, int b, int val)
{
if (l == a && r == b) downOn(v, val);
else {
Down(v);
int m = l + r >> ;
if (a <= m) multSum( * v, l, m, a, min(m, b), val);
if (m + <= b) multSum( * v + , m + , r, max(m + , a), b, val);
Union(v);
}
} void addSum(int v, int l, int r, int x, int val)
{
if (l == r) sum[v] = val;
else {
Down(v);
int m = l + r >> ;
if (x <= m) addSum( * v, l, m, x, val);
else addSum( * v + , m + , r, x, val);
Union(v);
}
} int Inv(int a)
{
int p = mod - ;
int res = ;
while (p) {
if (p & ) res = ll(res) * a % mod;
p >>= ; a = ll(a) * a % mod;
}
return res;
} int main()
{
n = ; scanf("%d %d", &val[n], &q);
for (int i = ; i < q; i++) {
scanf("%d %d", &a[i], &b[i]);
if (a[i] == ) {
scanf("%d", &c[i]);
n++; P[n] = b[i];
neigh[b[i]].push_back(n);
}
}
Traverse();
createMult(, , R[]);
createSum(, , R[]);
n = ;
for (int i = ; i < q; i++)
if (a[i] == ) {
n++;
ch[b[i]]++;
int tomult = ll(ch[b[i]] + ) * Inv(ch[b[i]]) % mod;
updMult(, , R[], L[b[i]], R[b[i]], tomult);
multSum(, , R[], L[b[i]], R[b[i]], tomult);
val[n] = c[i];
tomult = getMult(, , R[], L[n]);
addSum(, , R[], L[n], ll(tomult) * val[n] % mod);
} else {
int res = getSum(, , R[], L[b[i]], R[b[i]]);
if (P[b[i]]) {
int tomult = Inv(getMult(, , R[], L[P[b[i]]]));
res = ll(res) * tomult % mod;
}
printf("%d\n", res);
}
return ;
}

E.Cross Sum(待填坑)

cf Round 607的更多相关文章

  1. CF Round #551 (Div. 2) D

    CF Round #551 (Div. 2) D 链接 https://codeforces.com/contest/1153/problem/D 思路 不考虑赋值和贪心,考虑排名. 设\(dp_i\ ...

  2. CF Round #510 (Div. 2)

    前言:没想到那么快就打了第二场,题目难度比CF Round #509 (Div. 2)这场要难些,不过我依旧菜,这场更是被\(D\)题卡了,最后\(C\)题都来不及敲了..最后才\(A\)了\(3\) ...

  3. UOJ #30. [CF Round #278] Tourists

    UOJ #30. [CF Round #278] Tourists 题目大意 : 有一张 \(n\) 个点, \(m\) 条边的无向图,每一个点有一个点权 \(a_i\) ,你需要支持两种操作,第一种 ...

  4. 竞赛题解 - CF Round #524 Div.2

    CF Round #524 Div.2 - 竞赛题解 不容易CF有一场下午的比赛,开心的和一个神犇一起报了名 被虐爆--前两题水过去,第三题卡了好久,第四题毫无头绪QwQ Codeforces 传送门 ...

  5. 【前行&赛时总结】◇第4站&赛时9◇ CF Round 513 Div1+Div2

    ◇第4站&赛时9◇ CF Round 513 Div1+Div2 第一次在CF里涨Rating QWQ 深感不易……作blog以记之 ( ̄▽ ̄)" +Codeforces 的门为你打 ...

  6. CF Round #600 (Div 2) 解题报告(A~E)

    CF Round #600 (Div 2) 解题报告(A~E) A:Single Push 采用差分的思想,让\(b-a=c\),然后观察\(c\)序列是不是一个满足要求的序列 #include< ...

  7. CF Round #580(div2)题解报告

    CF Round #580(div2)题解报告 T1 T2 水题,不管 T3 构造题,证明大约感性理解一下 我们想既然存在解 \(|a[n + i] - a[i]| = 1\) 这是必须要满足的 既然 ...

  8. CF round #622 (div2)

    CF Round 622 div2 A.简单模拟 B.数学 题意: 某人A参加一个比赛,共n人参加,有两轮,给定这两轮的名次x,y,总排名记为两轮排名和x+y,此值越小名次越前,并且对于与A同分者而言 ...

  9. 【cf补题记录】Codeforces Round #607 (Div. 2)

    比赛传送门 这里推荐一位dalao的博客-- https://www.cnblogs.com/KisekiPurin2019/ A:字符串 B:贪心 A // https://codeforces.c ...

随机推荐

  1. mysql基本操作

    1.创建表:create table if not exists student(id integer(4) primary key auto_increment,name varchar(10),s ...

  2. SQL SERVER 2008 R2数据库出现“远程过程调用失败”(0x800706be)错误,怎么办!!

    以前SQL Server 2008 不能登陆的时候,总是通过“计算机管理”→“SQL Server服务”更改一下,"SQL Server(MSSQLSERVER)". 可是现在出现 ...

  3. 理解CSV文件以及ABAP中的相关操作

    在很多ABAP开发中,我们使用CSV文件,有时候,关于CSV文件本身的一些问题使人迷惑.它仅仅是一种被逗号分割的文本文档吗? 让我们先来看看接下来可能要处理的几个相关组件的词汇的语义. Separat ...

  4. crm on premise IFD 部署下提供oauth 2.0 集成自定义应用

    很多情况下我们的CRM系统会和弟三方应用集成,一般情况我们会开发一个中间站点来提供web api 给弟三方应用. 参考:http://alexanderdevelopment.net/post/201 ...

  5. SharePoint 2013 工作流之使用Designer配置示例篇

    在SharePoint 2013中,支持SharePoint Designer 2013(以下简称SPD)配置简单的工作流,完成我们的业务需要.下面,我们就举一个小例子,实现SPD配置工作流. 1. ...

  6. SharePoint 2013 图文开发系列之InfoPath入门

    本文主要介绍SharePoint 2013中,简单发布InfoPath表单,并添加后台代码,示例比较简单,主要描述的是一个创建InfoPath的过程,而非多么深奥的后台代码,希望能够给初学者带来帮助. ...

  7. Linux0.11内核--加载可执行二进制文件之1.copy_strings

    从现在开始就是分析最后的核心模块exec.c了,分析完这个文件后,就会和之前的所有分析形成一个环路,从创建进程.加载进程程序到进程调度.内存管理. exec.c的核心do_execve函数很长,而且用 ...

  8. android AsyncTask介绍

    AsyncTask是android提供的轻量级的异步类,可以直接继承AsyncTask,在类中实现异步操作,并提供接口反馈当前异步执行的程度(可以通过接口实现UI进度更新),最后反馈执行的结果给UI主 ...

  9. 移动端App广告常见的10种形式

    什么是App广告?   App广告,或称In-App广告,是指智能手机和平板电脑这类移动设备中第三方应用程序内置广告,属于移动广告的子类别. App广告兴起得益于其载体—App的风行.平板电脑和大屏触 ...

  10. AFN3.0封装

    总结了一下AFN3.0封装,也借鉴了其他人总结的,整理如下,希望多交流,互相进步 // // XJYSessionManager.h// // Created by XJY on 16/10/17. ...