A.Assigning Workstations && BZOJ 4425
Input
Output
#include<iostream>
#include<cstdio>
#include<vector>
#include<cstring>
#include<algorithm>
#include<set>
using namespace std;
typedef long long ll;
const int maxn = 3e5 + 10;
multiset<int>st;
multiset<int>::iterator it;
int n,m;
struct node
{
int s;
int e;
bool operator < (const node &w) const
{
return s < w.s;
}
}q[maxn];
int main()
{
while(~scanf("%d %d",&n,&m))
{
int a,s;
st.clear();
for(int i = 1;i <= n;i++)
{
scanf("%d %d",&a,&s);
q[i].s = a;
q[i].e = a + s;
}
sort(q + 1,q + 1 + n);
int ans = 0;
for(int i = 1;i <= n;i++)
{
int tmp = q[i].s - m;
//if(tmp <= 0)
//tmp = 1;
//cout<<i<<' '<<tmp<<endl;
if(st.size() == 0)
{
ans++;
st.insert(q[i].e);
//vt.push_back(q[i].e);
}
else
{
it = st.lower_bound(tmp);
if(it == st.end())
{
ans++;
st.insert(q[i].e);
//vt.push_back(q[i].e);
}
else
{
if((*it) > q[i].s)
{
ans++;
st.insert(q[i].e);
//vt.push_back(q[i].e);
}
else
{
st.erase(it);
st.insert(q[i].e);
//vt.push_back(q[i].e);
}
}
}
}
printf("%d\n",n - ans);
}
return 0;
}
/*
3 5
1 5
7 20
1 10
3 5
1 5
6 3
14 6
3 5
1 10
2 9
3 8
3 5
1 10
2 3
4 6
4 10000
1 1
3 2
4 6
6 2
*/
Input
Output
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn = 1e6 +10;
const ll inf = 1e18;
ll dp[maxn];
ll r,p;
ll ceil(int a,int b)
{
return (a + b - 1)/b;
}
ll dfs(int n)
{
if(n <= 1)
return 0;
if(dp[n])
return dp[n];
ll res = inf;
for(int i = 2;i <= n;i++)
{
res = min(res,dfs(ceil(n,i)) + (ll)(i - 1) * p + r);
}
return dp[n] = res ;
}
int main()
{
int n;
memset(dp,0,sizeof dp);
while(~scanf("%d %lld %lld",&n,&r,&p))
{
printf("%lld\n",dfs(n));
}
return 0;
}
我们就要推导下标啦。
总之就是要解这个方程
x、i、n为非负整数,已知n、i,求最小的x
ps : 下面这个式子是因为你随着分的块越多,i越大,那么这个i就是当前块, 最长区间为ceil(n/i) 。因为我们要跳过重复的,
所以要直接找到下一个块数 x.他们两个区间长度差1
有两种方法
第一种:看Claris博客,得到x = (n - 1) / ((n - 1) / i) + 1(这里的除均为整除)
第二种:
首先要知道
(具体数学里面有)
带入,得到
同乘上x
因为我们要求x的最小值,所以我们只看左边的不等式
因为x为非负整数,左边不一定是整数,那么x的最小值应该是
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn = 1e6 +10;
const ll inf = 1e18;
ll dp[maxn];
ll r,p;
ll ceil(int a,int b)
{
return (a + b - 1)/b;
}
ll dfs(int n)
{
if(n <= 1)
return 0;
if(dp[n])
return dp[n];
ll res = (ll)(n - 1) * p + r;
for(int i = 2;i < n;i = ceil(n,(ceil(n,i) - 1)))
{
res = min(res,dfs(ceil(n,i)) + (ll)(i - 1) * p + r);
}
return dp[n] = res ;
}
int main()
{
int n;
while(~scanf("%d %lld %lld",&n,&r,&p))
{
memset(dp,0,sizeof dp);
printf("%lld\n",dfs(n));
}
return 0;
}
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<vector>
#include<set>
#include<map>
using namespace std;
typedef long long ll;
const int maxn = 1e4+5;
struct node
{
ll x, y, v;
char sb;
}a[maxn];
int n;
vector<int> g[maxn];
int match[maxn], vis[maxn];
ll val[maxn];
bool dfs(int x)
{
int len = g[x].size();
for(int i = 0; i < len; i++)
{
int to = g[x][i];
if(!vis[to])
{
vis[to] = 1;
if(!match[to] || dfs(match[to]))
{
match[to] = x;
return 1;
}
}
}
return 0;
}
int Hungary()
{
int res = 0;
memset(match, 0, sizeof(match));
for(int i = 1; i <= n; i++)
{
memset(vis, 0, sizeof(vis));
res += dfs(i);
}
return res;
}
int main(void)
{
while(cin >> n)
{
int cnt = 1;
map<ll, int> m;
set<int> s;
s.clear(), m.clear();
for(int i = 1 ; i <= n; i++)
g[i].clear();
for(int i = 1; i <= n; i++)
{
scanf("%I64d%I64d", &a[i].x, &a[i].y);
ll add = a[i].x+a[i].y;
ll sub = a[i].x-a[i].y;
ll fac = a[i].x*a[i].y;
if(s.find(add) == s.end()) m[add] = cnt++, s.insert(add);
if(s.find(sub) == s.end()) m[sub] = cnt++, s.insert(sub);
if(s.find(fac) == s.end()) m[fac] = cnt++, s.insert(fac);
g[i].push_back(m[add]);
g[i].push_back(m[sub]);
g[i].push_back(m[fac]);
val[m[add]] = add;
val[m[sub]] = sub;
val[m[fac]] = fac;
}
int ans = Hungary();
// cout << ans << endl;
if(ans != n) puts("impossible");
else
{
for(int i = 1; i < cnt; i++)
if(match[i])
a[match[i]].v = val[i];
for(int i = 1; i <= n; i++)
{
if(a[i].v == a[i].x+a[i].y) a[i].sb = '+';
if(a[i].v == a[i].x-a[i].y) a[i].sb = '-';
if(a[i].v == a[i].x*a[i].y) a[i].sb = '*';
}
for(int i = 1; i <= n; i++)
printf("%I64d %c %I64d = %I64d\n", a[i].x, a[i].sb, a[i].y, a[i].v);
}
}
return 0;
}
/*
4
1 5
3 3
4 5
-1 -6
4
-4 2
-4 2
-4 2
-4 2
*/
G Guessing Camels && BZOJ 4430 BIT求偏序对 OR cdq分治+BIT
答案 = 总对数 - 不满足条件的对数.
现在就是考虑怎么求不满足的对数.这里巧妙的利用了BIT
我们可以发现不满足偏序性质的这一对,一定是在某两个排列里位置是相同的,只有一个和他们的位置不相同,那么我们可以对每两个排列求一次不满足题意的偏序对的个数.但是这样算的话 对于那个排列里位置不同的数对,在另两个排列被算了两次,所以把最后的答案除以2就是最终的结果了.
求偏序对的话就是对于两个排列x,y. 先预处理处理x 中每一个x[i]的位置i,然后从后往前遍历 y[i].
那么关于一个点对x,y,若它们在两个排列中
____y__u______x____k
_______x___________y
这样从后向前扫第二个排列,扫到y的时候在第一个排列y的位置+1,然后扫到x的时候查询第一个排列x位置的前缀和,前缀和即为不满足条件的对数
所以就对扫到的每一个数都这样做就行了
即
将第二个排列中所有偏序对的位置固定下来作为一个标准,那么从后往前遍历第二个排列时,假设遍历到第i个,那么第i个后面所有的数都在他的后面了,由于我们把i后面的数都在第一个排列中的对应位置+1,那么现在我们求一下第二个排列中的第i个数在第一个排列中对应位置前面有多少个数,就可以求出不满足的偏序对个数了,好好体会..
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<set>
#include<vector>
#include<queue>
#include<map>
#define inf 0x3f3f3f3f
using namespace std;
typedef long long ll;
const ll mod=1e9+7;
const int maxn=2e5+10;
int t[maxn],pos[maxn];
int A[maxn],B[maxn],C[maxn];
int n;
int lowbit(int x)
{
return x&-x;
}
void add(int x,int d)
{
while(x<maxn)
{
t[x]+=d;
x+=lowbit(x);
}
}
int sum(int x)
{
int res= 0;
while(x)
{
res += t[x];
x -= lowbit(x);
}
return res;
}
ll solve(int *x,int *y)
{
for(int i=1;i<=n;i++)
pos[x[i]]=i,t[i]=0;
ll res=0;
for(int i=n;i>=1;i--)
res+=sum(pos[y[i]]),add(pos[y[i]],1);
return res;
}
int main()
{
while(~scanf("%d",&n))
{
for(int i=1;i<=n;i++) scanf("%d",&A[i]);
for(int i=1;i<=n;i++) scanf("%d",&B[i]);
for(int i=1;i<=n;i++) scanf("%d",&C[i]);
ll ans = (ll) n*(n-1)/2;
ll res;
res= solve(A,B)+solve(B,C)+solve(A,C);
printf("%lld\n",ans - res/2);
}
return 0;
}
签到题
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
typedef long long ll;
const int maxn = 32;
ll fac[maxn] = {1, 2};
char str[maxn];
int main(void)
{
for(int i = 2; i < maxn; i++)
fac[i] = fac[i-1]*2;
while(cin >> str)
{
ll len = strlen(str);
ll x = 0, y = 0, p = fac[len-1];
for(int i = 0; i < len; i++)
{
if(str[i] == '0') ;
else if(str[i] == '1') y += p;
else if(str[i] == '2') x += p;
else x += p, y += p;
p /= 2;
}
// cout << x << ' ' << y << ' ' << p << endl;
printf("%I64d %I64d %I64d\n", len, y, x);
}
return 0;
}
给你 x^(x<<1) 的结果 让你求x,观察到x最大255 所以反过来逆推打个表就好
#include <iostream>
#include <cstring>
#include <cstdio>
using namespace std;
const int maxn = 1e5 + 5;
int a[maxn], ans[maxn];
void init()
{
for(int i = 0; i <= 255; i++)
a[i] = (i^(i<<1))%256, ans[a[i]] = i;
}
int main()
{
int n;
init();
while(~scanf("%d", &n))
{
int x;
for(int i = 1; i <= n; i++)
{
scanf("%d", &x);
printf("%d%c", ans[x], i == n ? '\n' : ' ');
}
}
return 0;
}
K -Kitchen Combinatorics 细节题
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<vector>
#include<set>
#include<map>
using namespace std;
typedef long long ll;
const int maxn = 2e3+5;
const ll INF = 1e18;
int r, s, m, d, n, flag;
ll b[maxn], a[maxn][maxn], cnt1[maxn], cnt2[maxn], cnt3[maxn];
vector<int> g[maxn];
ll mul(ll a, ll b)
{
if(!a || !b) return 0;
if(INF/a < b)
{
flag = 1;
return 1;
}
return a*b;
}
int main(void)
{
while(cin >> r >> s >> m >> d >> n)
{
for(int i = 0; i < maxn; i++)
g[i].clear();
for(int i = 1; i <= r; i++)
scanf("%I64d", &b[i]);
for(int i = 1; i <= s; i++)
{
scanf("%I64d", &a[i][0]);
for(int j = 1; j <= a[i][0]; j++)
scanf("%I64d", &a[i][j]);
}
for(int i = s+1; i <= s+m; i++)
{
scanf("%I64d", &a[i][0]);
for(int j = 1; j <= a[i][0]; j++)
scanf("%I64d", &a[i][j]);
}
for(int i = s+m+1; i <= s+m+d; i++)
{
scanf("%I64d", &a[i][0]);
for(int j = 1; j <= a[i][0]; j++)
scanf("%I64d", &a[i][j]);
}
for(int i = 1; i <= n; i++)
{
int x, y;
scanf("%d%d", &x, &y);
g[x].push_back(y);
g[y].push_back(x);
}
ll ans = 0, inf = 0;
set<int> ss1;
set<int>::iterator it;
for(int i = 1; i <= s; i++)
{
ss1.clear();
ll tmp = 1;
flag = 0;
memset(cnt1, 0, sizeof(cnt1));
ll t = 1;
bool have = 0;
for(int ii = 1; ii <= a[i][0]; ii++)
{
have = 1;
if(!cnt1[a[i][ii]]) t = mul(t, b[a[i][ii]]);
// t *= b[a[i][ii]];
// else t += 1;
cnt1[a[i][ii]]++;
if(t > INF || t < 0) flag = 1;
}
if(!have) t = 0;
int len = g[i].size();
for(int ii = 0; ii < len; ii++)
ss1.insert(g[i][ii]);
// cout << t << endl;
// tmp *= t;
tmp = mul(tmp, t);
if(tmp > INF || tmp < 0) flag = 1;
if(!tmp) continue;
// if(i == 1) cout << '*' << tmp << endl;
for(int j = s+1; j <= s+m; j++)
{
ll tmp2 = tmp;
set<int> ss2; ss2.clear();
for(it = ss1.begin(); it != ss1.end(); it++)
ss2.insert(*it);
it = ss2.lower_bound(j);
if(it != ss2.end() && *it == j) continue;
t = 1, have = 0;
for(int z = 1; z < maxn; z++)
cnt2[z] = cnt1[z];
for(int jj = 1; jj <= a[j][0]; jj++)
{
// cout << i << ' ' << j << ' ' << jj << ' ' << a[j][jj] << endl;
have = 1;
if(!cnt2[a[j][jj]]) t = mul(t, b[a[j][jj]]);
// t *= b[a[j][jj]];
// else t += 1;
cnt2[a[j][jj]]++;
if(t > INF || t < 0) flag = 1;
}
// cout << have << endl;
// if(i == 1) cout << tmp << ' ' << t << endl;
if(!have) t = 0;
int len = g[j].size();
for(int jj = 0; jj < len; jj++)
ss2.insert(g[j][jj]);
// tmp2 *= t;
tmp2 = mul(tmp2, t);
// cout << tmp2 << endl;
// cout << "****" << t << endl;
if(tmp2 > INF || tmp2 < 0) flag = 1;
if(!tmp2) continue;
// if(j == 4) cout << tmp << endl;
for(int k = s+m+1; k <= s+m+d; k++)
{
set<int> ss3;
ss3.clear();
for(it = ss2.begin(); it != ss2.end(); it++)
ss3.insert(*it);
it = ss3.lower_bound(k);
if(it != ss3.end() && *it == k) continue;
t = 1, have = 0;
ll tmp3 = tmp2;
for(int z = 1; z < maxn; z++)
cnt3[z] = cnt2[z];
for(int kk = 1; kk <= a[k][0]; kk++)
{
have = 1;
if(!cnt3[a[k][kk]])
t = mul(t, b[a[k][kk]]);
// t *= b[a[k][kk]];
// else t += 1;
cnt3[a[k][kk]]++;
if(t > INF || t < 0) flag = 1;
}
// cout << tmp3 << ' ' << t << ' ' << flag << endl;
if(!have) t = 0;
// tmp3 *= t;
tmp3 = mul(tmp3, t);
if(tmp3 > INF || tmp3 < 0) flag = 1;
if(!tmp3) continue;
if(flag == 1) inf = 1;
else
{
// cout << i << ' ' << j << ' ' << k << ' ' << tmp3 << endl;
ans += tmp3;
// cout << "***" << ans << endl;
// for(int z = 1; z <= r; z++)
// if(cnt3[z] == 3) ans += b[z];
if(ans > INF || ans < 0) inf = 1;
}
}
}
}
if(inf) puts("too many");
else printf("%I64d\n", ans);
}
return 0;
}
/*
6 1 1 1 0
2 3 1 5 3 2
2 1 2
3 3 4 5
1 6
3 2 2 1 1
2 3 2
1 1
1 2
1 2
1 3
1 1
2 3
3 1 1 1 1
5 5 5
3 1 2 3
3 1 2 3
3 1 2 3
2 1
10 1 1 1 0
100 100 100 100 100 100 100 100 100 100
4 1 2 3 4
3 5 6 7
3 8 9 10
6 1 1 1 1
2 3 1 5 3 2
2 1 2
3 3 4 5
1 6
1 3
10 1 1 1 1
100 100 100 100 100 100 100 100 100 100
4 1 2 3 4
3 5 6 7
3 8 9 10
1 3
4 1 1 1 0
100 100 100 2
1 4
3 1 2 3
3 1 2 3
2 1 1 1 0
100 100
2 1 2
2 1 2
2 1 2
3 2 2 2 0
2 3 4
2 1 3
2 2 3
2 1 3
2 2 3
2 1 3
2 2 3
9 1 1 1 0
100 100 100 100 100 100 100 100 100
9 1 2 3 4 5 6 7 8 9
9 1 2 3 4 5 6 7 8 9
9 1 2 3 4 5 6 7 8 9
*/