AM学军OJ

T1 暴力

 #include<bits/stdc++.h>

 using namespace std;

 typedef long long LL;
const int N = + ; int len, power; int get_next(int x) {
return x / + x % * power;
} int vis[N], clk; LL calc(int l, int r) {
LL ans = ;
for(int i = l; i <= r; i++) if(vis[i] != clk) {
int c = , x = i;
for(int j = ; j < len; j++) {
if(l <= x && x <= r && vis[x] != clk) {
vis[x] = clk, c++;
}
//cout << x << endl;
x = get_next(x);
}
//cout << "--" << ans << endl;
ans += c * (c - ) / ;
}
return ans;
} int main() { int T;
scanf("%d", &T);
while(T--) {
//memset(vis, 0, sizeof vis);
clk++;
int l, r, x;
scanf("%d%d", &l, &r); x = l;
for(len = , power = ; x; x /= ) len++, power *= ;
power /= ;
//cerr << "!" << endl;
//printf("%d\n", calc(l, r));
cout << calc(l, r) << endl;
} return ;
}

T2 最短路 比赛的时候统计方案的时候由u更新v的最短路以后直接把到v的最短路方案赋为1而不是u的方案数。

 #include<bits/stdc++.h>

 using namespace std;

 const int N =  + , mod = ;

 int d[N][N], g[N][N], f[N][N], n;
bool done[N][N]; int encode(int x, int y) {
return x << | y;
}
void discode(int s, int &x, int &y) {
x = s >> ;
y = s & (( << ) - );
} typedef pair<int, int> pii; priority_queue<pii, vector<pii>, greater<pii> > q; void insert(int x, int y, int z, int k) {
if(d[x][y] > z) {
d[x][y] = z;
f[x][y] = k;
q.push(pii(z, encode(x, y)));
} else if(d[x][y] == z) {
f[x][y] += k;
if(f[x][y] >= mod) f[x][y] -= mod;
}
} const int dx[] = {, , , -};
const int dy[] = {, -, , }; bool inmap(int x, int y) {
return <= x && x < n && <= y && y < n;
} void dijkstra() {
memset(done, , sizeof done);
memset(d, 0x3f, sizeof d);
insert(, , g[][], );
while(!q.empty()) {
int x, y;
discode(q.top().second, x, y); q.pop();
if(done[x][y]) continue;
done[x][y] = ;
if(x + y == n - ) continue;
for(int k = ; k < ; k++) {
int xx = x + dx[k], yy = y + dy[k];
if(!inmap(xx, yy)) continue;
insert(xx, yy, d[x][y] + g[xx][yy], f[x][y]);
}
}
} int main() {
while(~scanf("%d", &n) && n) {
for(int i = ; i < n; i++) {
for(int j = ; j < n; j++) {
scanf("%d", g[i] + j);
if(i + j >= n) {
int x = n - - j, y = n - - i;
//printf("(%d,%d) (%d,%d)\n", i, j, x, y);
g[x][y] += g[i][j];
g[i][j] = ;
}
}
}
dijkstra();
int ans = ~0u >> , res = ;
for(int i = ; i < n; i++) {
ans = min(ans, d[i][n - i - ]);
}
for(int i = ; i < n; i++) {
if(d[i][n - i - ] == ans) {
(res += f[i][n - i - ]) %= mod;
}
}
printf("%d\n", res);
}
return ;
}

T3 题目转化为对于$n$个二元组$(e_1,e_2)e_1,e_2$代表两条边,如果这两条边中的一条加入了图中,则对答案贡献1,图不能成环,求答案的最大值。

如果不是二元组而是一元组也就是一条边,就用最大生成树即可,最大生成树为什么是对的呢?拟阵可以证明。也就是说对于任意一个中间状态,如果这条边能够加进来(即没有自环),那么一定有一种最优解会包含这条边,用在这里也同理。当我们想加入一个二元组的时候,如果$e_1,e_2$中的一条可以直接加进去,那就直接加进去,如果都不能,就考虑删掉环上一条边,而删掉了这条边就要加入那个二元组的另一条边,这类似于二分图最大匹配的过程。

PM

T1 二分答案

 #include<bits/stdc++.h>

 using namespace std;

 const int N =  + ;

 int L[N], R[N], S[N];
int n; bool check(double v) {
double T = ;
for(int i = ; i < n; i++) {
T += S[i] / v;
if(T > R[i]) return ;
if(T < L[i]) T = L[i];
}
return ;
} int main() {
freopen("express.in", "r", stdin);
freopen("express.out", "w", stdout); scanf("%d", &n);
for(int i = ; i < n; i++) {
scanf("%d%d%d", L + i, R + i, S + i);
}
double l = , r = 1e15;
check();
while(r - l > 1e-) {
double mid = (l + r) / ;
if(check(mid)) r = mid;
else l = mid;
} printf("%.2f\n", l);
return ;
}

T2 dp 在比赛的时候,只写了j <= i而没有写j <= K导致数组溢出,数组只开了101却用到了101这个位置。

 #include<bits/stdc++.h>

 using namespace std;

 const int N =  + ;

 int n, K;

 char s[N];

 int f[N][][][]; // 前i位改变了j个0和k个1,第i位为l

 void maxit(int &x, int y) {
if(x < y) x = y;
} int main() {
freopen("welcome.in", "r", stdin);
freopen("welcome.out", "w", stdout);
cerr << ((sizeof f) >> ) << endl; scanf("%d%d", &n, &K); scanf("%s", s + );
for(int i = ; i <= n; i++) {
s[i] = s[i] == 'z';
} memset(f, -0x3f, sizeof f);
if(s[] == ) {
f[][][][] = ;
f[][][][] = ;
}
else {
f[][][][] = ;
f[][][][] = ;
}
for(int i = ; i < n; i++) {
for(int j = ; j <= i && j <= K; j++) {
for(int k = ; j + k <= i && k <= K; k++) {
int t1 = max(f[i][j][k][], f[i][j][k][]),
t2 = max(f[i][j][k][] + , f[i][j][k][]);
if(s[i+] == ) {
maxit(f[i+][j][k][], t1);
maxit(f[i+][j+][k][], t2);
} else {
maxit(f[i+][j][k][], t2);
maxit(f[i+][j][k+][], t1);
}
}
}
} int ans = ; for(int i = ; i <= K; i++) {
maxit(ans, f[n][i][i][]);
maxit(ans, f[n][i][i][]);
} printf("%d\n", ans); return ;
}

T3

题目描述】
A是某公司的CEO,每个月都会有员工把公司的盈利数据送给A,A是个与众不同的怪人,A不注重盈利还是亏本,而是喜欢研究“完美序列”:连续的互不相同的序列。A想知道区间[L,R]之间最长的完美序列。
【输入格式】
第一行两个整数N,M(1<=N,M<=200000),N表示连续N个月,编号为0到N-1,M表示询问的次数。第二行N个整数(绝对值不
超过106),第i个数表示该公司第i个月的盈利值。接下来M行每行两个整数L,R(0<=L<=R<=N-1),表示A询问的区间。

【输出格式】
输出M行,每行一个整数对应询问区间内的完美序列的最长长度。
【样例输入】
9 2
2 5 4 1 2 3 6 2 4
0 8
2 6
4 8
【样例输出】
6
5
4

这道题网上普遍流传着一个算法,就是统计出以每个位置为前缀的最长长度,这个显然是不减的,然后对于询问区间内的最最长度,前一段可能超过了$L_i$,这时取最靠右的位置,后面一段没有超过,直接询问最大值。

我的做法是在线段树上加上等差数列的标记,并需要离线处理。

 #include<bits/stdc++.h>

 using namespace std;

 typedef pair<int, int> pii;
#define FI first
#define SE second
const int N = + ; #define mid ((l + r) >> 1)
#define ls s << 1, l, mid
#define rs s << 1 | 1, mid + 1, r
int tag[N * ], val[N * ]; void add_tag(int s, int l, int r, int d) {
tag[s] = max(tag[s], d);
val[s] = max(val[s], d);
} void down(int s, int l, int r) {
add_tag(ls, tag[s]);
add_tag(rs, tag[s] - (mid - l + ));
} void modify(int s, int l, int r, int L, int R) {
if(L <= l && r <= R) return add_tag(s, l, r, (R - L + ) - (l - L));
down(s, l, r);
if(L <= mid) modify(ls, L, R);
if(mid < R) modify(rs, L, R);
val[s] = max(val[s], val[s << ]);
val[s] = max(val[s], val[s << | ]);
} int query(int s, int l, int r, int L, int R) {
if(L <= l && r <= R) return val[s];
down(s, l, r);
int res = ;
if(L <= mid) res = max(res, query(ls, L, R));
if(mid < R) res = max(res, query(rs, L, R));
return res;
} int n, m, a[N];
int ql[N], qr[N], id[N], ans[N];
bool vis[ + ]; bool cmp(int a, int b) {
return qr[a] < qr[b];
} int main() {
freopen("diff.in", "r", stdin);
freopen("diff.out", "w", stdout); scanf("%d%d", &n, &m);
for(int i = ; i < n; i++) {
scanf("%d", a + i); a[i] += ;
}
for(int i = ; i < m; i++) {
scanf("%d%d", ql + i, qr + i);
id[i] = i;
}
sort(id, id + m, cmp);
for(int l = , r = , i = ; r < n; r++) {
while(vis[a[r]]) {
vis[a[l++]] = ;
}
vis[a[r]] = ;
modify(, , n-, l, r);
while(i < m && qr[id[i]] == r) {
ans[id[i]] = query(, , n-, ql[id[i]], r);
i++;
}
} for(int i = ; i < m; i++) {
printf("%d\n", ans[i]);
}
return ;
}

2016-11-15NOIP模拟赛的更多相关文章

  1. 9.11 myl模拟赛

    9.11 myl 模拟赛 100 + 100 + 0 第一题耗费了太多的时间,导致最后一题没有时间想,直接去写了暴力,而且出题人没有给暴力分.... Problem 1. superman [题目描述 ...

  2. 2017.6.11 NOIP模拟赛

    题目链接: http://files.cnblogs.com/files/TheRoadToTheGold/2017-6.11NOIP%E6%A8%A1%E6%8B%9F%E8%B5%9B.zip 期 ...

  3. 11.17 模拟赛&&day-2

    /* 后天就要复赛了啊啊啊啊啊. 可能是因为我是一个比较念旧的人吧. 讲真 还真是有点不舍. 转眼间一年的时间就过去了. 2015.12-2016.11. OI的一年. NOIP gryz RP++. ...

  4. 2014.11.12模拟赛【美妙的数字】| vijos1904学姐的幸运数字

    美妙的数字(number.c/.cpp/.pas) 题目描述 黄巨大认为非负整数是美妙的,并且它的数值越小就越美妙.当然0是最美妙的啦. 现在他得到一串非负整数,对于每个数都可以选择先对它做二进制非运 ...

  5. 2014.11.12模拟赛【最小公倍数】| vijos1047最小公倍数

    最小公倍数(lcm.c/.cpp/.pas) 题目描述 给定两个正整数,求他们的最小公倍数. 样例输入 28 12 样例输出 84 数据范围 对于40%数据:1<=a,b<=10^9 对于 ...

  6. 11.7NOIP模拟赛解题报告

    心路历程 预计得分:\(50 + 100 + 100\) 实际得分:\(50 + 100 +100\) T2 T3两道数据结构题美滋滋,然而写完就过去\(3h\)美滋滋 T1数学题学弟们都会做Orzz ...

  7. 11.6NOIP模拟赛解题报告

    心路历程 预计得分:\(100 + 100 + 100 = 300\) 实际得分:\(100 +100 +100 = 300\) 学OI两年终于AK了一次qwq(虽然题目炒鸡水..) 纪念一下这令人激 ...

  8. 11.5NOIP模拟赛解题报告

    心路历程 预计得分:\(100 + 40 + 30 = 170\) 实际得分:\(100 +100 + 50 = 250\) 辣鸡数据毁我青春 T1一眼不会做感觉要凉 T2好像一波折半搜索就做完了 T ...

  9. 11.1NOIP模拟赛解题报告

    心路历程 预计得分:\(100 + 100 + 50\) 实际得分:\(100 + 100 + 50\) 感觉老师找的题有点水呀. 上来看T1,woc?裸的等比数列求和?然而我不会公式呀..感觉要凉 ...

  10. 11.7noip模拟赛

     题解:广义斐波那契数列 矩阵乘法 #include<iostream> #include<cstdio> #include<cstring> #define LL ...

随机推荐

  1. 【产品体验】eyepetizer开眼

    第一次写博客,内心还有点小激动呢~~本人产品新人,学习中,希望大家多多指教!  先来两张开眼的界面图坐镇——         开眼简介: appetizer for eyes 即 eyepetizer ...

  2. 深入研究java.lang.ProcessBuilder类

     深入研究java.lang.ProcessBuilder类 一.概述       ProcessBuilder类是J2SE 1.5在java.lang中新添加的一个新类,此类用于创建操作系统进程,它 ...

  3. Ural1387 Vasya's Dad

    Description Vasya's dad is good in maths. Lately his favorite objects have been "beautiful" ...

  4. 《ArcGIS Engine+C#实例开发教程》第五讲 鹰眼的实现

    原文:<ArcGIS Engine+C#实例开发教程>第五讲 鹰眼的实现 摘要:所谓的鹰眼,就是一个缩略地图,上面有一个矩形框,矩形框区域就是当前显示的地图区域,拖动矩形框可以改变当前地图 ...

  5. Android开发中一些被冷落但却很有用的类和方法

    MediaMetadataRetriever 顾名思义,就是用来获取媒体文件一些相关信息的类.包括一首歌的标题,作者,专辑封面和名称,时长,比特率等等.如果是视频的话,可以获取视频的长宽,预览图. h ...

  6. 【Python】代码行数统计

    两级目录,可扩展为N级. # Count the line of dir or file import os, fnmatch, fileinput def ChkFileType(lst): tmp ...

  7. [Hadoop源码解读](六)MapReduce篇之MapTask类

    MapTask类继承于Task类,它最主要的方法就是run(),用来执行这个Map任务. run()首先设置一个TaskReporter并启动,然后调用JobConf的getUseNewAPI()判断 ...

  8. 函数page_rec_get_next_const

    /************************************************************//** Gets the pointer to the next recor ...

  9. Webform——服务器控件与客户端控件

    Webform,即BS,浏览器应用. 关于服务器和客户端,在Webform 中,  服务器就相当于后台(也就是编辑C#代码的地方), 客户端相当于前台(也就是Html页面). 用法: ①如果想在服务器 ...

  10. C#中的几个线程同步对象方法

    在编写多线程程序时无可避免会遇到线程的同步问题.什么是线程的同步呢? 举个例子:如果在一个公司里面有一个变量记录某人T的工资count=100,有两个主管A和B(即工作线程)在早一些时候拿了这个变量的 ...