Code:
#include <bits/stdc++.h>
using namespace std ;
int main(){
int n , S ;
cin >> n >> S ;
int res = S / n ;
S -= res * n ;
if( S ) res ++ ;
cout << res << endl ;
return 0 ;
}
Code:
思路不清晰写出来像一坨shi
#include <bits/stdc++.h>
#define LL long long
using namespace std ;
const int AX = 1e5 + 666 ;
LL a[AX] ;
int main(){
int n , m ;
cin >> n >> m ;
for( int i = 0 ; i < n ; i++ ){
cin >> a[i] ;
}
if( n == 1 ){
cout << 0 << endl;
return 0 ;
}
sort( a , a + n );
LL res = 0LL ;
int cur = a[n-1] + 1 ;
for( int i = n - 1 ; i > 0 ; i-- ){
if( a[i] == a[i-1] ){
res += a[i] - 1 ;
cur -- ;
}else{
if( cur - 1 <= a[i-1] ){
res += a[i] - 1 ;
cur -- ;
}else{
res += a[i-1] ;
res += a[i] - cur + 1 ;
cur = a[i-1] + 1 ;
}
}
if( cur <= 2 ){
for( int j = i - 1 ; j >= 0 ; j-- ){
res += a[j] - 1 ;
}
break ;
}
}
if( cur > 2 ){
res += a[0] - cur + 1 ;
}
cout << res << endl;
return 0 ;
}
思路清晰版本:
#include <bits/stdc++.h>
#define LL long long
using namespace std ;
const int AX = 1e5 + 666 ;
LL a[AX] ;
int main(){
int n , m ;
cin >> n >> m ;
LL sum = 0LL ;
for( int i = 1 ; i <= n ; i++ ){
cin >> a[i] ;
sum += a[i] ;
}
sort( a + 1 , a + n + 1 ) ;
LL cur = a[n] ;
LL res = 0LL ;
for( int i = n ; i >= 1 ; i-- ){
res += max( 1LL , cur - a[i-1] ) ;
cur = min( cur - 1 , a[i-1] ) ;
}
cout << sum - res << endl ;
return 0 ;
}
C
题意:找出有多少个a数组的子序列b , 使得b1,b2,b3…bk, 对于每个bi , i 整除 bi
思路:dp[i][j] 表示到第 i 个数 子串b 长度 j 且满足条件的数量。
dp[i][j] = dp[i-1][j-1] + dp[i][j] .
但是…开不了这么大的,那么就要省掉一维。
先预处理出1e6的因子,从大到小存,这是为了后面正序遍历(也可以倒序因子正序,只要保证先访问大因子就行)的时候 前面小的因子 不会影响 i 的结果,而i的结果是由i-1得到的。
Code:
#include <bits/stdc++.h>
#define LL long long
using namespace std ;
const int AX = 1e6 + 666 ;
const int MOD = 1e9 + 7 ;
int dp[AX] = { 1 } ;
int n ;
std::vector<int> v[AX];
void getFac(){
for( int i = 1000000 ; i >= 1 ; i-- ){
for( int j = i ; j <= 1000000 ; j += i ){
v[j].push_back(i) ;
}
}
}
int main(){
getFac() ;
scanf("%d",&n) ;
int x ;
for( int i = 1 ; i <= n ; i++ ){
scanf("%d",&x) ;
for( int j = 0 ; j < v[x].size() ; j++ ){
int id = v[x][j] ;
dp[id] += dp[id-1] ;
dp[id] %= MOD ;
}
}
LL res = 0LL ;
for( int i = 1 ; i <= n ; i++ ){
res += dp[i] ;
res %= MOD ;
}
cout << res << endl;
return 0 ;
}
思路:
让 r 从大到小遍历 , 按照 l 从小到大排序,每次二分查找比当前 r 大的数,如果这个数所在的集合左端点<= r ,那么就往后继续找满足的解,直到到头了或者x < y * ( r - l ) ,也就是开一个新的TV集合会更省钱。
最后记得加上没人组合的,独自一个集合。
Code:
#include <bits/stdc++.h>
#define LL long long
#define INF 1000000007
using namespace std ;
const int MOD = 1e9 + 7 ;
const int AX = 1e5 + 666 ;
int mark[AX] ;
struct Node{
LL l , r ;
int id ;
bool friend operator < ( const Node &a , const Node &b ){
return ( ( a.l == b.l && a.r < b.r ) || a.l < b.l ) ;
}
}a[AX];
struct NO{
LL l , r ;
int id ;
}c[AX];
Node b[AX] ;
int n ;
LL x , y ;
bool cmp( NO a , NO b ){
return a.r > b.r ;
}
int binary_search( LL x ){
int l = 0 , r = n - 1 ;
while( l <= r ){
int mid = ( l + r ) >> 1 ;
if( a[mid].l > x ){
r = mid - 1 ;
}else{
l = mid + 1 ;
}
}
return l ;
}
int main(){
scanf("%d%I64d%I64d",&n,&x,&y) ;
for( int i = 0 ; i < n ; i ++ ){
scanf("%I64d%I64d",&a[i].l,&a[i].r) ;
a[i].id = i ;
c[i].id = i ;
c[i].l = a[i].l ;
c[i].r = a[i].r ;
}
memset( mark , 0 , sizeof(mark) ) ;
sort( a , a + n ) ;
sort( c , c + n , cmp ) ;
LL res = 0LL ;
int tot = 1 ;
for( int i = 0 ; i <= n ; i++ ){
b[i].l = INF ;
b[i].r = 0 ;
}
for( int i = 0 ; i < n ; i++ ){
int pos = binary_search( c[i].r ) ;
if( pos < 0 || pos >= n || ( 1LL * y * ( a[pos].l - c[i].r ) > x ) ){
continue;
}
int id ;
if( !mark[a[pos].id] ){
mark[c[i].id] = tot ;
mark[a[pos].id] = tot ;
id = tot ++ ;
}else{
id = mark[a[pos].id] ;
if( b[id].l <= c[i].r ){
while( pos < n && ( 1LL * y * ( a[pos].l - c[i].r ) < x ) && b[mark[a[pos].id]].l <= c[i].r ) pos ++ ;
if( pos < n && ( 1LL * y * ( a[pos].l - c[i].r ) < x ) && b[mark[a[pos].id]].l > c[i].r ){
if( !mark[a[pos].id] ){
mark[c[i].id] = tot ;
mark[a[pos].id] = tot ;
id = tot ++ ;
}else{
id = mark[a[pos].id] ;
}
}else continue ;
}
mark[c[i].id] = id ;
}
b[id].l = min( b[id].l , c[i].l ) ;
b[id].r = max( b[id].r , a[pos].r ) ;
}
for( int i = 1 ; i < tot ; i++ ){
res = ( res + x % MOD + 1LL * y * ( b[i].r - b[i].l ) % MOD ) % MOD ;
}
for( int i = 0 ; i < n ; i++ ){
if( !mark[a[i].id] ){
res = ( res + x % MOD + 1LL * y * ( a[i].r - a[i].l ) % MOD ) % MOD ;
}
}
printf("%I64d\n",res);
return 0 ;
}
简洁Code:
#include <bits/stdc++.h>
#define LL long long
#define INF 1000000007
using namespace std ;
const int MOD = 1e9 + 7 ;
const int AX = 1e5 + 666 ;
int n ;
LL a[AX];
LL b[AX];
int mark[AX] ;
LL x , y ;
int main(){
scanf("%d%I64d%I64d",&n,&x,&y) ;
LL res = 0LL ;
for( int i = 0 ; i < n ; i ++ ){
scanf("%I64d%I64d",&a[i],&b[i]) ;
res = ( res + x % MOD + 1LL * y * ( b[i] - a[i] ) ) % MOD ;
}
memset( mark , 0 , sizeof(mark) ) ;
sort( a , a + n ) ;
sort( b , b + n ) ;
for( int i = n - 1 ; i >= 0 ; i-- ){
int pos = upper_bound( a , a + n , b[i] ) - a ;
if( pos < 0 || pos >= n || ( 1LL * y * ( a[pos] - b[i] ) > x ) ){
continue;
}
while( pos <= n && mark[pos] && ( 1LL * y * ( a[pos] - b[i] ) < x ) ) pos ++ ;
if( pos >= n ) continue ;
if( 1LL * y * ( a[pos] - b[i] ) < x ){
mark[pos] = 1 ;
res = ( res + MOD - x + 1LL * y * ( a[pos] - b[i] ) ) % MOD ;
}
}
printf("%I64d\n",res);
return 0 ;
}