Codeforces 954 dijsktra 离散化矩阵快速幂DP 前缀和二分check
A
B
C
D
给你一个联通图 给定S,T 要求你加一条边使得ST的最短距离不会减少 问你有多少种方法
因为N<=1000 所以N^2枚举边数 迪杰斯特拉两次 求出Sdis 和 Tdis 如果dis[i]+dis[j]+1>=distance(s,t)&&dis[j]+dis[i]+1>=distance(i,j)就为一条要求边
- #include <bits/stdc++.h>
- #define PI acos(-1.0)
- #define mem(a,b) memset((a),b,sizeof(a))
- #define TS printf("!!!\n")
- #define pb push_back
- #define inf 1e9
- //std::ios::sync_with_stdio(false);
- using namespace std;
- //priority_queue<int,vector<int>,greater<int>> que; get min
- const double eps = 1.0e-10;
- const double EPS = 1.0e-4;
- typedef pair<int, int> pairint;
- typedef long long ll;
- typedef unsigned long long ull;
- //const int maxn = 3e5 + 10;
- const int maxn = ;
- const int turn[][] = {{, }, { -, }, {, }, {, -}};
- const int turn2[][] = {{, }, { -, }, {, }, {, -}, {, -}, { -, -}, {, }, { -, }};
- //priority_queue<int, vector<int>, less<int>> que;
- //next_permutation
- string a;
- vector<int> gra[];
- int from, to;
- int anser;
- int n, m, s, t;
- int sum;
- int tong[][];
- int sdis[];
- int tdis[];
- void getsdis()
- {
- for (int i = ; i <= n; i++)
- {
- if (i == s)
- {
- continue;
- }
- sdis[i] = INT_MAX;
- }
- queue<int> que;
- que.push(s);
- while (!que.empty())
- {
- int now = que.front();
- que.pop();
- int len = gra[now].size();
- for (int i = ; i < len; i++)
- {
- int to = gra[now][i];
- if (sdis[to] > sdis[now] + )
- {
- sdis[to] = sdis[now] + ;
- que.push(to);
- }
- }
- }
- }
- void gettdis()
- {
- for (int i = ; i <= n; i++)
- {
- if (i == t)
- {
- continue;
- }
- tdis[i] = INT_MAX;
- }
- queue<int> que;
- que.push(t);
- while (!que.empty())
- {
- int now = que.front();
- que.pop();
- int len = gra[now].size();
- for (int i = ; i < len; i++)
- {
- int to = gra[now][i];
- if (tdis[to] > tdis[now] + )
- {
- tdis[to] = tdis[now] + ;
- que.push(to);
- }
- }
- }
- }
- int main()
- {
- cin >> n >> m >> s >> t;
- for (int i = ; i <= m; i++)
- {
- scanf("%d %d", &from, &to);
- gra[from].pb(to);
- gra[to].pb(from);
- tong[from][to] = tong[to][from] = ;
- }
- sum = (n - ) * n / ;
- getsdis();
- gettdis();
- int mindis = sdis[t];
- // cout << mindis << endl;
- // for (int i = 1; i <= n; i++)
- // {
- // cout << sdis[i] << " ";
- // }
- // cout << endl;
- // for (int i = 1; i <= n; i++)
- // {
- // cout << tdis[i] << " ";
- // }
- // cout << endl;
- for (int i = ; i <= n - ; i++)
- {
- for (int j = i + ; j <= n; j++)
- {
- if (tong[i][j])
- {
- continue;
- }
- if (sdis[i] + tdis[j] + >= mindis && sdis[j] + tdis[i] + >= mindis)
- {
- anser++;
- }
- }
- }
- cout << anser << endl;
- return ;
- }
E
给你N个水管 每个水管流出的水的温度是恒定的 但是流量是可控的 给你一个温度T问你每秒最多的流量是多少
按每个水管的温度排序 然后贪心
- #include <bits/stdc++.h>
- #define PI acos(-1.0)
- #define mem(a,b) memset((a),b,sizeof(a))
- #define TS printf("!!!\n")
- #define pb push_back
- #define inf 1e9
- //std::ios::sync_with_stdio(false);
- using namespace std;
- //priority_queue<int,vector<int>,greater<int>> que; get min
- const double eps = 1.0e-10;
- typedef pair<int, int> pairint;
- typedef long long ll;
- typedef unsigned long long ull;
- //const int maxn = 3e5 + 10;
- const int maxn = ;
- const int turn[][] = {{, }, { -, }, {, }, {, -}};
- const int turn2[][] = {{, }, { -, }, {, }, {, -}, {, -}, { -, -}, {, }, { -, }};
- //priority_queue<int, vector<int>, less<int>> que;
- //next_permutation
- //double a[200005];
- //double t[200005];
- pair<double, double> wendu[];
- int n;
- double T;
- double anser;
- int flag = ;
- double nowx, nowy;
- bool cmp(pair<double, double> a, pair<double, double> b)
- {
- if (a.second == b.second)
- {
- return a.first < b.first;
- }
- return a.second < b.second;
- }
- int main()
- {
- cin >> n >> T;
- for (int i = ; i <= n; i++)
- {
- scanf("%lf", &wendu[i].first);
- }
- for (int i = ; i <= n; i++)
- {
- scanf("%lf", &wendu[i].second);
- }
- sort(wendu + , wendu + + n, cmp);
- int left = ;
- int right = n;
- for (int i = ; i <= n; i++)
- {
- nowx += 1.0 * wendu[i].first * wendu[i].second;
- nowy += wendu[i].first;
- }
- //printf("%.8f\n", nowx);
- //printf("%.8f\n", nowy);
- if (fabs(nowx / nowy - T) < eps)
- {
- printf("%.7f\n", nowy);
- return ;
- }
- else if (nowx / nowy - T > eps)
- {
- while (fabs(nowx / nowy - T) > eps)
- {
- if (wendu[right].second <= T)
- {
- flag = ;
- break;
- }
- double nextx, nexty;
- nextx = nowx - 1.0 * wendu[right].first * wendu[right].second;
- nexty = nowy - wendu[right].first;
- if (nextx / nexty - T > eps)
- {
- nowx = nextx;
- nowy = nexty;
- right--;
- }
- else
- {
- anser = nowy - (nowx - 1.0 * T * nowy) / (wendu[right].second - T);
- printf("%.7f\n", anser);
- return ;
- }
- }
- if (flag)
- {
- printf("%.7f\n", nowy);
- }
- }
- else
- {
- while (fabs(nowx / nowy - T) > eps)
- {
- if (wendu[left].second >= T)
- {
- flag = ;
- break;
- }
- double nextx, nexty;
- nextx = nowx - 1.0 * wendu[left].first * wendu[left].second;
- nexty = nowy - wendu[left].first;
- if (nextx / nexty - T < eps)
- {
- nowx = nextx;
- nowy = nexty;
- left++;
- }
- else
- {
- anser = nowy - (1.0 * T * nowy - nowx) / (T - wendu[left].second);
- printf("%.7f\n", anser);
- return ;
- }
- }
- if (flag)
- {
- printf("%.7f\n", nowy);
- }
- }
- if (!flag)
- {
- cout << << endl;
- }
- return ;
- }
F
给你一个三行的M列的矩阵(M<=1e18) 有N个障碍 要求从(2,1)开始到(2,M)结束 有多少种方法%MOD
先把矩阵离散化为2*N+1个矩阵 然后分情况用矩阵快速幂算答案
- #include <bits/stdc++.h>
- #define PI acos(-1.0)
- #define mem(a,b) memset((a),b,sizeof(a))
- #define TS printf("!!!\n")
- #define pb push_back
- #define inf 1e9
- //std::ios::sync_with_stdio(false);
- using namespace std;
- //priority_queue<int,vector<int>,greater<int>> que; get min
- const double eps = 1.0e-10;
- const double EPS = 1.0e-4;
- typedef pair<int, int> pairint;
- typedef long long ll;
- typedef unsigned long long ull;
- //const int maxn = 3e5 + 10;
- const int turn[][] = {{, }, { -, }, {, }, {, -}};
- //priority_queue<int, vector<int>, less<int>> que;
- //next_permutation
- ll Mod = ;
- class Matrix//定义一个矩阵结构体
- {
- public:
- ll M[][];
- clear()
- {
- mem(M, );
- }
- init()
- {
- clear();
- for (int i = ; i < ; i++)
- {
- M[i][i] = ;
- }
- }
- Matrix()//初始化
- {
- mem(M, );
- }
- Matrix(ll Arr[][])//用数组来初始化
- {
- for (int i = ; i < ; i++)
- for (int j = ; j < ; j++)
- {
- M[i][j] = Arr[i][j];
- }
- }
- };
- Matrix operator * (Matrix A, Matrix B) //重载乘法运算符
- {
- Matrix Ans;
- Ans.clear();
- for (int i = ; i < ; i++)
- for (int j = ; j < ; j++)
- for (int k = ; k < ; k++)
- {
- Ans.M[i][j] = (Ans.M[i][j] + 1LL * A.M[i][k] * B.M[k][j] % Mod) % Mod;
- }
- return Ans;
- }
- Matrix MFPOW(Matrix now, ll n)
- {
- Matrix x;
- x.init();
- while (n)
- {
- if (n & )
- {
- x = x * now;
- }
- now = now * now;
- n >>= 1ll;
- }
- return x;
- }
- void print(Matrix x)
- {
- for (int i = ; i < ; i++)
- {
- for (int j = ; j < ; j++)
- {
- cout << x.M[i][j] << " ";
- }
- cout << endl;
- }
- }
- struct block
- {
- ll where, from, to;
- };
- ll a[][] = {{, , }, {, , }, {, , }};
- ll b[][] = {{, , }, {, , }, {, , }};
- ll m;
- block now[];
- ll num[];
- int judge[][];
- int check[];
- int pop = ;
- int cnt = ;
- int main()
- {
- //freopen("sample.txt", "w", stdout);
- int n;
- cin >> n;
- cin >> m;
- ll from, to, where;
- num[pop++] = , num[pop++] = m;
- for (int i = ; i <= n; i++)
- {
- scanf("%lld %lld %lld", &where, &from, &to);
- num[pop++] = from - , num[pop++] = to; //将边界输入以便离散化 注意:如果L要减1以防出现错误
- now[i].where = where, now[i].from = from, now[i].to = to;
- }
- sort(num + , num + pop);
- int len = unique(num + , num + pop) - num - ;//因为数列是从下标1开始的所以还要再减去1
- for (int i = ; i <= n; i++)
- {
- int L = lower_bound(num + , num + len + , now[i].from) - num;
- int R = lower_bound(num + , num + len + , now[i].to) - num;
- judge[now[i].where][L]++;
- judge[now[i].where][R + ]--; //因为要用到前缀和来维护每一块的第now[i].where行是否有障碍 所以要[R+1]--
- }
- Matrix ans(a);
- Matrix B(b);
- for (int i = ; i <= len; i++)
- {
- ll lenth = num[i] - num[i - ];
- //cout << lenth << endl;
- Matrix cur(b);
- for (int j = ; j <= ; j++)
- {
- check[j] += judge[j][i];
- if (check[j])
- {
- cur.M[][j - ] = cur.M[][j - ] = cur.M[][j - ] = ;
- }
- }
- //print(cur);
- cur = MFPOW(cur, lenth);
- //print(cur);
- ans = ans * cur;
- //print(ans);
- }
- cout << ans.M[][] << endl;
- return ;
- }
G
给你一个N位数的数列代表城墙 每一个城墙上面初始有A[i]个弓箭手 给你一个R 弓箭手可以防守[i-R,i+R]的地方
再给你K(K<=1e18)个弓箭手 问你每个城墙能被防守的最大最小值为多少
先前缀和处理出原始的防守值 然后二分答案用前缀和check是否能满足
- #include <bits/stdc++.h>
- #define PI acos(-1.0)
- #define mem(a,b) memset((a),b,sizeof(a))
- #define TS printf("!!!\n")
- #define pb push_back
- #define inf 1e9
- //std::ios::sync_with_stdio(false);
- using namespace std;
- //priority_queue<int,vector<int>,greater<int>> que; get min
- const double eps = 1.0e-10;
- const double EPS = 1.0e-4;
- typedef pair<int, int> pairint;
- typedef long long ll;
- typedef unsigned long long ull;
- //const int maxn = 3e5 + 10;
- const int maxm = ;
- const int turn[][] = {{, }, { -, }, {, }, {, -}};
- //priority_queue<int, vector<int>, less<int>> que;
- //next_permutation
- ll pre[];
- ll judgepre[];
- int n, r;
- ll k;
- bool judge(ll x)
- {
- mem(judgepre, );
- ll remain = k;
- ll need;
- ll now = ;
- for (int i = ; i <= n; i++)
- {
- now += judgepre[i];
- if (pre[i] + now < x)
- {
- need = x - pre[i] - now;
- remain -= need;
- if (remain < )
- {
- return false;
- }
- judgepre[i + ] += need;
- if (i + * r + <= n)
- {
- judgepre[i + * r + ] -= need;
- }
- }
- }
- return true;
- }
- int main()
- {
- cin >> n >> r >> k;
- ll now;
- for (int i = ; i <= n; i++)
- {
- scanf("%lld", &now);
- pre[max(, i - r)] += now;
- if (i + r + <= n)
- {
- pre[i + r + ] -= now;
- }
- }
- for (int i = ; i <= n; i++)
- {
- pre[i] = pre[i] + pre[i - ];
- }
- // for(int i=1;i<=n;i++)
- // cout<<pre[i]<<" ";
- // cout<<endl;
- ll l = , r = 2e18 + 2e9;
- ll mid;
- ll anser;
- while (l <= r)
- {
- mid = (l + r) >> ;
- if (judge(mid))
- {
- anser = mid;
- l = mid + ;
- }
- else
- {
- r = mid - ;
- }
- }
- cout << anser << endl;
- }
Codeforces 954 dijsktra 离散化矩阵快速幂DP 前缀和二分check的更多相关文章
- codeforces 691E 矩阵快速幂+dp
传送门:https://codeforces.com/contest/691/problem/E 题意:给定长度为n的序列,从序列中选择k个数(可以重复选择),使得得到的排列满足xi与xi+1异或的二 ...
- Codeforces 576D Flights for Regular Customers 矩阵快速幂+DP
题意: 给一个$n$点$m$边的连通图 每个边有一个权值$d$ 当且仅当当前走过的步数$\ge d$时 才可以走这条边 问从节点$1$到节点$n$的最短路 好神的一道题 直接写做法喽 首先我们对边按$ ...
- CodeForces - 691E Xor-sequences 【矩阵快速幂】
题目链接 http://codeforces.com/problemset/problem/691/E 题意 给出一个长度为n的序列,从其中选择k个数 组成长度为k的序列,因为(k 有可能 > ...
- P1357 花园 (矩阵快速幂+ DP)
题意:一个只含字母C和P的环形串 求长度为n且每m个连续字符不含有超过k个C的方案数 m <= 5 n <= 1e15 题解:用一个m位二进制表示状态 转移很好想 但是这个题是用矩阵快速 ...
- BZOJ1009 矩阵快速幂+DP+KMP
Problem 1009. -- [HNOI2008]GT考试 1009: [HNOI2008]GT考试 Time Limit: 1 Sec Memory Limit: 162 MBSubmit: ...
- Codeforces 691E Xor-sequences(矩阵快速幂)
You are given n integers a1, a2, ..., an. A sequence of integers x1, x2, ..., xk is called a & ...
- COJ 1208 矩阵快速幂DP
题目大意: f(i) 是一个斐波那契数列 , 求sum(f(i)^k)的总和 由于n极大,所以考虑矩阵快速幂加速 我们要求解最后的sum[n] 首先我们需要思考 sum[n] = sum[n-1] + ...
- Codeforces 989E A Trance of Nightfall 矩阵快速幂+DP
题意:二维平面上右一点集$S$,共$n$个元素,开始位于平面上任意点$P$,$P$不一定属于$S$,每次操作为选一条至少包含$S$中两个元素和当前位置$P$的直线,每条直线选取概率相同,同一直线上每个 ...
- BZOJ1009: [HNOI2008]GT考试 (矩阵快速幂 + DP)
题意:求一个长度为n的数字字符串 (n <= 1e9) 不出现子串s的方案数 题解:用f i,j表示长度为i匹配到在子串j的答案 用kmp的失配函数预处理一下 然后这个转移每一个都是一样的 所以 ...
随机推荐
- mysql数据库修改一行数据格式不成功问题
举个例子: mysql数据库中有两个字段publication_time.storage_time,我尝试着一个一个的修改字段的状态 #alter table books modify column ...
- 使用指定MTU到特定IP
ping指令使用指定MTU到特定IP 命令如下 45.58.185.18 这里MTU为1300
- JS调用服务器端方法
javascript函数中执行C#代码中的函数:方法一:1.首先建立一个按钮,在后台将调用或处理的内容写入button_click中; 2.在前台写一个js函数,内容为document. ...
- 读取yaml中的内容
def read_yml(path): """ 读取yml文件中的数据 :param path: 文件yaml 的路径 :return: 返回读取yaml文件内的结果 & ...
- CSS3—— 分页 框大小 弹性盒子 多媒体查询 多媒体查询实例
分页 网站有很多个页面,就需要使用分页来为每个页面做导航 点击及鼠标悬停分页样式 圆角样式 悬停过度效果 带边框的分页 分页间隔 分页字体大小 居中分页 面包屑导航 框大小 box-sizing 属性 ...
- Django 基于角色的权限控制
有一种场景, 要求为用户赋予一个角色, 基于角色(比如后管理员,总编, 编辑), 用户拥有相应的权限(比如管理员拥有所有权限, 总编可以增删改查, 编辑只能增改, 有些页面的按钮也只有某些角色才能查看 ...
- 【DSP开发】【Linux开发】基于ARM+DSP进行应用开发
针对当前应用的复杂性,SOC芯片更好能能满足应用和媒体的需求,集成众多接口,用ARM做为应用处理器进行多样化的应用开发和用户界面和接口,利用DSP进行算法加速,特别是媒体的编解码算法加速,既能够保持算 ...
- linux 正则表达式 目录
linux 通配符与正则表达式 linux 通配符 linux 正则表达式 使用grep命令 linux 扩展正则表达式 egrep linux 正则表达式 元字符
- Android的Monkey和MonkeyRunner
本文部分解释性语段摘自网络百科或其它BLOG,语句内容网络随处可见,也不知道谁是初始原创,便不再署名出处,如有雷同,还请见谅. Monkey 什么是Monkey Monkey是Android中的一个命 ...
- AcWing 875. 快速幂
题目链接:https://www.acwing.com/problem/content/description/877/ 快速幂模板题,计算ab mod p 的值,a,b,p大概1e9左右,可以快速计 ...