总体感觉比以往的only div2简单点
A. Bear and Raspberry
签到题,求的是 max (x [ i ] - x [ i + 1 ]) - m 1 <= i < n
#include <set>
#include <map>
#include <list>
#include <queue>
#include <stack>
#include <cmath>
#include <string>
#include <cstdio>
#include <vector>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
#define PB push_back
#define SIZE(x) (int)x.size()
#define clr(x,y) memset(x,y,sizeof(x))
#define MP(x,y) make_pair(x,y)
#define RS(n) scanf ("%s", n)
#define ALL(t) (t).begin(),(t).end()
#define FOR(i,n,m) for (int i = n; i <= m; i ++)
#define ROF(i,n,m) for (int i = n; i >= m; i --)
#define IT iterator
#define FF first
#define SS second
typedef long long ll;
typedef unsigned int uint;
typedef unsigned long long ull;
typedef vector<int> vint;
typedef vector<string> vstring;
typedef pair<int, int> PII;
void RI (int& x){
x = 0;
char c = getchar ();
while (!(c>='0' && c<='9' || c=='-')) c = getchar ();
bool flag = 1;
if (c == '-'){
flag = 0;
c = getchar ();
}
while (c >= '0' && c <= '9'){
x = x * 10 + c - '0';
c = getchar ();
}
if (!flag) x = -x;
}
void RII (int& x, int& y){RI (x), RI (y);}
void RIII (int& x, int& y, int& z){RI (x), RI (y), RI (z);}
void RC (char& c){
c = getchar ();
while (c == ' '||c == '\n') c = getchar ();
}
char RC (){
char c = getchar ();
while (c == ' '||c == '\n') c = getchar ();
return c;
}
/**************************************END define***************************************/
const ll mod = 1e9+7;
const ll LINF = 1e18;
const int INF = 1e9;
const double EPS = 1e-8;
int main (){
int n, m;
cin >> n >> m;
vint vec;
FOR (i, 1, n){
int t;
cin >> t;
vec.PB (t);
}
int maxx = 0;
FOR (i, 1, SIZE (vec) - 1){
maxx = max (maxx, (vec[i-1] - vec[i]));
}
maxx -= m;
cout << max (maxx, 0) << endl;
}
B. Bear and Strings
长度为5000的字符串,求有多少对i, j 使得s (i, j)子串存在“bear"
由于字符串只有5000,直接n^2暴力就好,不过应该有更高效的做法,没多作考虑
#include <set>
#include <map>
#include <list>
#include <queue>
#include <stack>
#include <cmath>
#include <string>
#include <cstdio>
#include <vector>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
#define PB push_back
#define SIZE(x) (int)x.size()
#define clr(x,y) memset(x,y,sizeof(x))
#define MP(x,y) make_pair(x,y)
#define RS(n) scanf ("%s", n)
#define ALL(t) (t).begin(),(t).end()
#define FOR(i,n,m) for (int i = n; i <= m; i ++)
#define ROF(i,n,m) for (int i = n; i >= m; i --)
#define IT iterator
#define FF first
#define SS second
typedef long long ll;
typedef unsigned int uint;
typedef unsigned long long ull;
typedef vector<int> vint;
typedef vector<string> vstring;
typedef pair<int, int> PII;
void RI (int& x){
x = 0;
char c = getchar ();
while (!(c>='0' && c<='9' || c=='-')) c = getchar ();
bool flag = 1;
if (c == '-'){
flag = 0;
c = getchar ();
}
while (c >= '0' && c <= '9'){
x = x * 10 + c - '0';
c = getchar ();
}
if (!flag) x = -x;
}
void RII (int& x, int& y){RI (x), RI (y);}
void RIII (int& x, int& y, int& z){RI (x), RI (y), RI (z);}
void RC (char& c){
c = getchar ();
while (c == ' '||c == '\n') c = getchar ();
}
char RC (){
char c = getchar ();
while (c == ' '||c == '\n') c = getchar ();
return c;
}
/**************************************END define***************************************/
const ll mod = 1e9+7;
const ll LINF = 1e18;
const int INF = 1e9;
const double EPS = 1e-8;
int main (){
string s;
cin >> s;
int ans = 0;
FOR (i, 0, SIZE (s) - 1){
FOR (j, i, SIZE (s) - 4){
if (s[j]=='b' && s[j+1]=='e' && s[j+2]=='a' && s[j+3]=='r'){
ans += SIZE (s) - j - 3;
break;
}
}
}
cout << ans << endl;
}
C. Bear and Prime Numbers
感谢cf的服务器这么叼,10^7再乘个log都过了,就是利用筛法求素数的过程预处理
#include <set>
#include <map>
#include <list>
#include <queue>
#include <stack>
#include <cmath>
#include <string>
#include <cstdio>
#include <vector>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
#define PB push_back
#define SIZE(x) (int)x.size()
#define clr(x,y) memset(x,y,sizeof(x))
#define MP(x,y) make_pair(x,y)
#define RS(n) scanf ("%s", n)
#define ALL(t) (t).begin(),(t).end()
#define FOR(i,n,m) for (int i = n; i <= m; i ++)
#define ROF(i,n,m) for (int i = n; i >= m; i --)
#define IT iterator
#define FF first
#define SS second
typedef long long ll;
typedef unsigned int uint;
typedef unsigned long long ull;
typedef vector<int> vint;
typedef vector<string> vstring;
typedef pair<int, int> PII;
void RI (int& x){
x = 0;
char c = getchar ();
while (!(c>='0' && c<='9' || c=='-')) c = getchar ();
bool flag = 1;
if (c == '-'){
flag = 0;
c = getchar ();
}
while (c >= '0' && c <= '9'){
x = x * 10 + c - '0';
c = getchar ();
}
if (!flag) x = -x;
}
void RII (int& x, int& y){RI (x), RI (y);}
void RIII (int& x, int& y, int& z){RI (x), RI (y), RI (z);}
void RC (char& c){
c = getchar ();
while (c == ' '||c == '\n') c = getchar ();
}
char RC (){
char c = getchar ();
while (c == ' '||c == '\n') c = getchar ();
return c;
}
/**************************************END define***************************************/
const ll mod = 1e9+7;
const ll LINF = 1e18;
const int INF = 1e9;
const double EPS = 1e-8;
int a[10000005];
bool pr[10000005];
int ans[10000005];
int main (){
int n;
cin >> n;
FOR (i, 1, n){
int t;
cin >> t;
a[t] ++;
}
FOR (i, 2, 10000000){
if (pr[i] == 0){
ans[i] += a[i];
for (int j = 2; i * j <= 10000000; j ++){
pr[i*j] = true;
ans[i] += a[i*j];
}
}
}
FOR (i, 2, 10000000){
ans[i] += ans[i-1];
}
int q;
cin >> q;
while (q --){
int l, r;
cin >> l >> r;
l = min (l, 10000000);
r = min (r, 10000000);
cout << ans[r] - ans[l-1] << endl;
}
}
D. Bear and Floodlight
状压dp
dp[1<<n] , dp[ i ] 表示状态为 i 时能走到的最大x坐标,中间算坐标时用正弦定理简单推一下就行了
#include <set>
#include <map>
#include <list>
#include <queue>
#include <stack>
#include <cmath>
#include <string>
#include <cstdio>
#include <vector>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
#define PB push_back
#define SIZE(x) (int)x.size()
#define clr(x,y) memset(x,y,sizeof(x))
#define MP(x,y) make_pair(x,y)
#define RS(n) scanf ("%s", n)
#define ALL(t) (t).begin(),(t).end()
#define FOR(i,n,m) for (int i = n; i <= m; i ++)
#define ROF(i,n,m) for (int i = n; i >= m; i --)
#define IT iterator
#define FF first
#define SS second
typedef long long ll;
typedef unsigned int uint;
typedef unsigned long long ull;
typedef vector<int> vint;
typedef vector<string> vstring;
typedef pair<int, int> PII;
void RI (int& x){
x = 0;
char c = getchar ();
while (!(c>='0' && c<='9' || c=='-')) c = getchar ();
bool flag = 1;
if (c == '-'){
flag = 0;
c = getchar ();
}
while (c >= '0' && c <= '9'){
x = x * 10 + c - '0';
c = getchar ();
}
if (!flag) x = -x;
}
void RII (int& x, int& y){RI (x), RI (y);}
void RIII (int& x, int& y, int& z){RI (x), RI (y), RI (z);}
void RC (char& c){
c = getchar ();
while (c == ' '||c == '\n') c = getchar ();
}
char RC (){
char c = getchar ();
while (c == ' '||c == '\n') c = getchar ();
return c;
}
/**************************************END define***************************************/
const ll mod = 1e9+7;
const ll LINF = 1e18;
const int INF = 1e9;
const double EPS = 1e-8;
const double PI = acos (-1.0);
double dp[1<<20];
bool vis[1<<20];
struct Point {
double x, y, angle;
friend double dist (const Point& a, const Point& b){
return sqrt ((a.x-b.x) * (a.x-b.x) + (a.y-b.y) * (a.y-b.y));
}
Point (double a, double b, double c):x(a), y(b), angle (c){}
};
void init (){
clr (vis, 0);
FOR (i, 0, (1<<20) - 1){
dp[i] = -LINF;
}
}
double cal (Point po, double x){
double d1 = dist (po, Point (x, 0, 0));
double ang1 = acos ((po.x - x) / d1);
double ang2 = PI - ang1 - po.angle;
if (ang2 <= 0) return INF;
return d1 * sin (po.angle) / sin (ang2) + x;
}
int main (){
//freopen ("1.txt", "r", stdin);
init ();
int n;
double l, r;
cin >> n >> l >> r;
vector<Point> vec;
FOR (i, 1, n){
double x, y, angle;
cin >> x >> y >> angle;
angle = PI * angle / 180.0;
vec.PB (Point (x, y, angle));
}
queue<int> q;
FOR (i, 0, n-1){
dp[1<<i] = cal (vec[i], l);
//cout << dp[1<<i][i] << endl;
q.push (1<<i);
vis[1<<i] = true;
}
while (SIZE (q)){
int tx = q.front ();
q.pop ();
vis[tx] = false;
FOR (i, 0, n-1){
if (!((1<<i) & tx)){
int sx = tx | (1<<i);
double t = cal (vec[i], dp[tx]);
if (t > dp[sx]){
dp[sx] = t;
if (!vis[sx]){
vis[sx] = true;
q.push (sx);
}
}
}
}
}
double maxx = dp[(1<<n) - 1];
maxx = min (maxx, r);
printf("%.12f\n", maxx - l);
}
E. Bear in the Field
矩阵快速幂,根据题意构造递推式
Sx[n] = Sx[n-1] + dx[n-1]
Sy[n] = Sy[n-1] + dy[n-1]
dx[n] = dx[n-1] + Sx[n] + Sy[n] + n - 1
dy[n] = dy[n-1] + Sx[n] + Sy[n] + n - 1
整理一下有
Sx[n] = Sx[n-1] + dx[n-1]
Sy[n] = Sy[n-1] + dy[n-1]
dx[n] = 2*dx[n-1] + dy[n-1] + Sx[n-1] + Sy[n-1] + n - 1
dy[n] = dx[n-1] + 2*dy[n-1] + Sx[n-1] + Sy[n-1] + n - 1
这样就变成了n和n-1的关系,可以用矩阵递推。
根据上面的递推式构造矩阵就可以,这步就不解释了
#include <set>
#include <map>
#include <list>
#include <queue>
#include <stack>
#include <cmath>
#include <string>
#include <cstdio>
#include <vector>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
#define PB push_back
#define SIZE(x) (int)x.size()
#define clr(x,y) memset(x,y,sizeof(x))
#define MP(x,y) make_pair(x,y)
#define RS(n) scanf ("%s", n)
#define ALL(t) (t).begin(),(t).end()
#define FOR(i,n,m) for (int i = n; i <= m; i ++)
#define ROF(i,n,m) for (int i = n; i >= m; i --)
#define IT iterator
#define FF first
#define SS second
typedef long long ll;
typedef unsigned int uint;
typedef unsigned long long ull;
typedef vector<int> vint;
typedef vector<string> vstring;
typedef pair<int, int> PII;
void RI (int& x){
x = 0;
char c = getchar ();
while (!(c>='0' && c<='9' || c=='-')) c = getchar ();
bool flag = 1;
if (c == '-'){
flag = 0;
c = getchar ();
}
while (c >= '0' && c <= '9'){
x = x * 10 + c - '0';
c = getchar ();
}
if (!flag) x = -x;
}
void RII (int& x, int& y){RI (x), RI (y);}
void RIII (int& x, int& y, int& z){RI (x), RI (y), RI (z);}
void RC (char& c){
c = getchar ();
while (c == ' '||c == '\n') c = getchar ();
}
char RC (){
char c = getchar ();
while (c == ' '||c == '\n') c = getchar ();
return c;
}
/**************************************END define***************************************/
const ll LINF = 1e18;
const int INF = 1e9;
const double EPS = 1e-8;
ll mod;
ll a[6][6] = {
1, 0, 1, 1, 0, 0,
0, 1, 1, 1, 0, 0,
1, 0, 2, 1, 0, 0,
0, 1, 1, 2, 0, 0,
0, 0, 1, 1, 1, 0,
0, 0, 0, 0, 1, 1
};
struct Mat {
ll t[6][6];
Mat () {
clr (t, 0);
}
void initUnit (){
FOR (i, 0, 5){
FOR (j, 0, 5){
t[i][j] = (i==j ? 1 : 0);
}
}
}
void modul (){
FOR (i, 0, 5){
FOR (j, 0, 5){
t[i][j] = (t[i][j]%mod + mod - 1) % mod + 1;
}
}
}
friend Mat operator * (const Mat& x, const Mat& y){
Mat t;
FOR (i, 0, 5){
FOR (j, 0, 5){
FOR (k, 0, 5){
t.t[i][j] += x.t[i][k] * y.t[k][j];
}
}
}
t.modul ();
return t;
}
friend Mat operator ^ (Mat x, ll n){
Mat ans;
ans.initUnit ();
while (n){
if (n & 1){
ans = ans * x;
}
x = x * x;
n >>= 1;
}
return ans;
}
};
int main (){
//freopen ("1.txt", "r", stdin);
cin >> mod;
ll sx, sy, dx, dy, t;
cin >> sx >> sy >> dx >> dy >> t;
dx += (sx + sy);
dy += (sx + sy);
dx = (dx%mod + mod - 1) % mod + 1;
dy = (dy%mod + mod - 1) % mod + 1;
vector<ll> vec;
vec.PB (sx), vec.PB (sy), vec.PB (dx), vec.PB (dy);
vec.PB (1), vec.PB (1);
Mat x;
FOR (i, 0, 5){
FOR (j, 0, 5){
x.t[i][j] = a[i][j];
}
}
x = x ^ t;
ll ax = 0LL, ay = 0LL;
FOR (k, 0, 5){
ax += vec[k] * x.t[k][0];
ax %= mod;
}
FOR (k, 0, 5){
ay += vec[k] * x.t[k][1];
ay %= mod;
}
ax = (ax+mod-1) % mod + 1;
ay = (ay+mod-1) % mod + 1;
cout << ax << " " << ay << endl;
}